首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >有没有可能让FORTRAN DLL每次加载到一个随机地址?

有没有可能让FORTRAN DLL每次加载到一个随机地址?
EN

Stack Overflow用户
提问于 2013-01-17 14:19:03
回答 1查看 428关注 0票数 0

我一直在搜索,但没有找到一个假定的编译器标志或某种东西,它允许我构建我的FORTRAN DLL (使用英特尔Visual Fortran Composer XE 2013编译器),以便每次加载随机基址。我在C++代码中显式地加载了我的FORTRAN DLL,加载/卸载都很好,但我只是注意到它每次加载到的地址是完全相同的位置。我想知道这是否就是为什么当我同时多次运行我的程序时,有时我的FORTRAN DLL加载成功,而另一些时候加载失败。英特尔Fortran编译器是否有随机基址编译器选项?我已经阅读了它的发行说明,但也没有运气。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-01-17 18:24:37

回答你直接的问题:是的,可以标记一个DLL,这样最近的Windows版本就可以在稍微随机的基地址加载它。这是通过向链接器(link.exe)传递/DYNAMICBASE选项来实现的。有关如何在Visual Studio中启用此功能的信息,请阅读链接页面。如果在makefile中的命令行上使用ifort,则可以使用/link选项将标志传递给链接器:

代码语言:javascript
运行
AI代码解释
复制
ifort.exe ... /link /DYNAMICBASE

请注意,/link选项应该是命令行中的最后一个选项,因为之后的所有内容都会传递给链接器。还要注意,默认情况下/DYNAMICBASE是打开的,您的库应该以稍微随机的地址加载(您运行的是Windows XP吗?)

然而,这并不是真正必要的。解释原因如下。

只是为了清楚地总结一下评论。Windows上的每个进程(不仅在Windows上,而且几乎在任何现代操作系统上,如*BSD、Linux、OS X等)具有自己的虚拟线性地址空间,并且用户空间中的所有内存都使用这些虚拟地址进行操作。虚拟内存被划分为多个页,这些页由物理内存帧支持。一个物理存储器帧可以映射到多个虚拟存储器页,甚至可以从不同进程的地址空间映射到许多虚拟存储器页,从而促进进程之间的存储器共享。在所谓的页面表中维护虚拟存储器页面和物理存储器帧之间的映射。它们对于进程是本地的,因此映射是本地的,这意味着两个不同进程中的相同虚拟内存地址很可能映射到完全不同的物理内存地址。一些操作系统(包括Windows)将每个进程的虚拟地址空间分成两部分--下层和上层。下半部分属于进程,而所有进程中的上半部分映射到操作系统的内核内存区。应用程序开发人员对此不感兴趣,因为内核内存不能从用户空间访问,因为他们缺乏必要的特权,因此只表现为可用虚拟内存空间的减少(例如,在32位系统上,4个GiB中只有2个或3个GiB可访问)。其他操作系统(其中OS是最流行的桌面操作系统)拥有进程专用的整个虚拟地址空间,内核在自己的单独虚拟内存空间中运行。

Window(和大多数其他实现虚拟内存管理的OSes )上的可执行文件通常由不同的部分组成,这些部分被分组为多个段。可执行文件格式的设计使得它可以通过将部分文件直接映射到虚拟地址空间来加载到内存中-这是一个称为内存映射的过程。通常,包含程序指令的可执行文件部分(通常命名为.text或类似的内容)是只读的,因此可以在从相同的可执行文件创建的或加载了相同DLL的所有进程之间共享(DLL也与可执行文件具有相同的结构,但包含不同的部分集,并且不能单独运行),以节省物理内存。可以有许多包含不同数据段的其它段,例如包含初始化的静态(也是全局)变量的.data段、包含未初始化的静态变量的.bss段、具有调试信息的段、重定位段、导入和导出表等。除非采取显式措施,否则读/写(数据)段通常不会在不同的进程之间共享。

Fortran公共块通常位于.bss部分,因为它们只是未初始化的静态数据。如果使用BLOCK DATA结构使用数据初始化公共块,则将其放入.data部分。无论采用哪种方式,公共块都以一个不能在加载DLL的不同进程之间共享的节结束。最后,当两个进程加载DLL时,无论是隐式地作为其依赖项的一部分,还是显式地使用LoadLibrary(),只读部分将在两个进程之间共享,但读写数据部分(包括公共块)在每个进程中将是不同的,并且对一个进程中的数据所做的修改在另一个进程中将不可见,即使在两个进程中的DLL是在相同的基址加载的。

Windows DLL有一个称为“首选基址”的功能。每当操作系统加载这样的DLL时,它都会尝试将其放在指定的首选基址。如果不能(例如,所需虚拟地址空间的一部分已经被占用),则它将库重新定位到不同的基地址。这种行为的原因是,DLL重新定位在Windows上代价很高,因为绝对寻址用于访问全局符号,并且无论何时必须重新定位库,都必须由加载器修补(修复)地址。相比之下,许多Unix系统的动态库都是PIC(位置无关代码),可以在任何基本虚拟地址加载。但是PIC代码的执行速度比普通的依赖于位置的代码要慢一些。

较老的Windows版本总是在相同的基址加载最基本的库,如USER32.DLLKERNEL32.DLL。它们的加载器是非常可预测的,如果你在启动和执行时以相同的顺序加载相同的库集,通常每次运行时库都会加载到相同的基本虚拟地址。自从Vista引入了地址空间布局的随机化后,这种情况发生了变化-这是一种可选功能,允许在随机化的虚拟基址加载特殊标记的可执行文件(和DLL),以使远程网络攻击更难找到各种操作系统或用户API调用的正确地址。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14381049

复制
相关文章
浏览器启动外部软件
常可以看见使用浏览器代码启动本地应用的软件.例如qq、迅雷、等等.那么他们是怎么做到的呢? 它的奥秘:Register protocol 前言我们经常看到 tencent://..thunde
晓晨
2018/06/22
2.2K0
Swift 中的属性包装器
当处理代表某种状态形式的属性时,通常会在每次修改值时触发某种关联的逻辑。例如,我们可以根据一组规则验证每个新值,可以以某种方式转换分配的值,或者每当值更改时都可以通知一组观察者。
韦弦zhy
2021/04/08
2.8K0
【C++】C++11的新特性 — function 包装器 , bind包装器
function包装器也叫作适配器。C++中的function本质是一个类模板,也是一个包装器。
叫我龙翔
2024/08/13
1570
【C++】C++11的新特性 — function 包装器 , bind包装器
Python 常用外部模块详解
RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统,他遵循Mozilla Public License开源协议,MQ全称为Message Queue,消息队列(MQ)是一种应用程序对应用程序的通信方法,应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们.消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术.排队指的是应用程序通过队列来通信,队列的使用除去了接收和发送应用程序同时执行的要求,说的笼统点是queue+socket实现.
王瑞MVP
2022/12/28
3860
【Nginx39】Nginx学习:upstream服务器组模块
最后一个重点模块内容啦,感谢坚持到现在的你和我。总算是向大佬的道路上又前进了一步了。今天的内容主要是服务器组的配置,其实更直白点,就是 Nginx 负载均衡的配置模块。会不会有小伙伴不明白负载均衡是啥?如果是新同学,还不明白的话,要自己查查资料补习一下了哦。
硬核项目经理
2023/11/08
9281
【Nginx39】Nginx学习:upstream服务器组模块
Nginx | Nginx增加模块
在上篇文章中安装 Nginx 时,因为我的系统中没有 zlib 库,因此无法直接编译 Nginx,需要忽略这个库。这个库的作用是让 Nginx 可以开启 gzip 来让 http 支持压缩功能。为了能够让我们的 Nginx 正常支持 gzip,我们需要安装 zlib 库,并且将忽略的库编译进来。具体步骤如下:
码农UP2U
2020/08/26
1K0
【c++11】包装器
包装器(Wrapper) 是一个常见的编程设计模式,通常用于封装或“包装”某个现有的对象、函数、数据结构或者操作,以提供额外的功能或简化接口。在不同的上下文中,包装器可能有不同的实现方式和目的,但核心思想都是“将现有功能封装起来,以实现更强的扩展性、易用性或者功能分离”。
用户11029103
2025/02/03
1090
【c++11】包装器
服务器-Nginx模块化结构
习惯上将Nginx分为:核心模块、标准模块、可选HTTP模块、邮件服务模块和第三方模块五大类。
小二三不乌
2018/08/02
4120
以第三方openresty提供的模块:echo-nginx-module 为例,演示如何给已经安装好的nginx添加外部模块
以第三方openresty提供的模块:echo-nginx-module 为例,演示如何给已经安装好的nginx添加外部模块。
青山师
2023/05/05
8880
Java-包装器类
所有的基本类型都有一个与之对应的类,这些类称为包装器类。对象包装器类是不可改变的,即一旦构造类包装器类,就不允许更改包装在其中的值。同时,对象包装器类还是final,因此不能定义它们的子类。
用户7886150
2021/02/02
6180
从模块外部访问内部成员
从模块外部访问内部成员 1.使用exports exports.js: var myMsg='hello'; var funcname = function () { return 'testMsg'; }; exports.msg = myMsg; exports.funcname = funcname; foo.js: var foo = require('./exports.js'); console.log(foo.msg); console.log(foo.funcname());
Dream城堡
2018/10/15
1.2K0
C++11的互斥包装器
在C++多线程中会经常用到mutex,在使用的时候lock后,有时候会忘记使用unlock进行解锁造成死锁,或者在lock和unlock之间代码异常跳出,导致程序无法执行到unlock造成死锁,因此在C++11中引入互斥体包装器,互斥体包装器为互斥提供了便利的RAII风格机制,本质上就是在包装器的构造函数中加锁,在析构函数中解锁,将加锁和解锁操作与对象的生存期深度绑定,防止使用mutex加锁(lock)后,忘记解锁(unlock)或者两者之间出现异常退出等造成死锁。
艰默
2023/11/17
2040
C++11的互斥包装器
【C++11】 包装器 | bind
function包装器 也被叫做 适配器 C++11中function本质是类模板,也是一个包装器
lovevivi
2023/10/17
2750
【C++11】 包装器 | bind
Linux服务器之Nginx动态添加模块
  已经安装好的Nginx,需要添加一个未被编译安装的模块,需要怎么弄呢? 这里已安装第三方nginx-rtmp-module模块为例
星哥玩云
2022/07/26
1.2K0
Nginx实用模块
Nginx 是一个很强大的高性能Web和反向代理应用。原先一直停留在apt install nginx 的阶段,直到开始深入了解其模块等,才发现:nginx厉害!!nginx除了基础功能以外还有很多有趣且实用的模块。因为nginx内置了许多变量(http://nginx.org/en/docs/varindex.html 部分是模块实现)、逻辑运算、指令,组合起来,就可以实现强大的功能。
yumusb
2020/04/22
9570
NGINX rewrite模块的笔记
因为最近的一个需求涉及到SEO 所以考虑用php写一套前台,这样可以根据url自动输出完整的页面,这里比较重要的是url rewrite 因为直接使用参数来访问页面一是不具备结构性,不方便基于文件夹管理php的前台页面,二是搜索引擎搜索方面也不友好。 所以要为后台添加一套自适应的rewrite。
雪碧君
2023/02/15
2400
Nginx 限流模块
【转载请注明出处】:https://cloud.tencent.com/developer/article/1623156
后端老鸟
2020/05/02
1.5K0
Nginx 限流模块
nginx 模块详解
worker_processes number | auto; worker进程的数量;通常应该为当前主机的cpu的物理核心数 worker_cpu_affinity auto [cpumask] #将work进程绑定在固定cpu上提高缓存命中率 例: worker_cpu_affinity 0001 0010 0100 1000; worker_cpu_affinity 0101 1010; worker_priority number 指定worker进程的nice值,设定worker进程优先级: [-20,20]    worker_rlimit_nofile number worker进程所能够打开的文件数量上限,默认较小,生产中需要调大如65535
星哥玩云
2022/07/26
1.9K0
nginx 模块详解
软件必备模块-软件的哲学
我一直觉得设计哲学这个东西是一个很虚的东西,直到我看了一个关于苏联暴力美学的帖子,里面有一段写ak-47,t34等等。虽然也有人说这是苏联的战略忽悠局。经过一年的工作发现确实生产中面临这样的问题,如果用苏军内幕这本书里面的思想确实是可以改进很多问题。
于欣轩
2018/05/23
8270
Nginx 模块(1)
加载一个模块的方法就是在配置的时候加上 --with-xxx_xxx_module ,禁用一个模块的方法就是在后面加上 --without-xxx_xxx_module
franket
2021/10/18
4280

相似问题

nginx解析器模块-负缓存

10

Postgres用now()查询外部数据包装器

10

Nginx服务器块中的括号包装冒号是什么?

10

如何使用nginx模块?

20

用模块构建NGINX?

20
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档