- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发一个 C 语言库,它应该与 C、C++ 或 Fortran 代码一起使用。它使用的一种机制是捕获对堆栈、堆或 data/bss 段中页面的写入。在这种情况下,“堆”是库从映射文件创建的特殊堆。我发现我的库无法捕获对 Fortran 应用程序中变量的写入。该变量声明为
double precision u(5,I,J,K)
其中 I、J 和 K 是整数参数(即常量)。然后,代码将 u 包含在称为“字段”的公共(public) block 中。
在GDB下调试时,发现u的地址没有落入三个数据段中任何一个的范围内。 (因此库无法捕获写入!)然后我查看了/proc//maps 伪文件,发现 u 的地址落入系统注释为“堆”的范围内。但你是如何进入这个“堆”的呢?在这种情况下,Fortran 77 代码不使用非标准的“allocate”关键字在堆上分配。有人可以向我解释 Fortran 77(在 Ubuntu Linux x86-64 下)在“堆”上分配哪些变量,以及这个“堆”首先是如何创建的吗?
最佳答案
我在公共(public) block 中使用了一个数组。看起来 Linux 中的 .bss 段确实与堆合并(或者至少使用相同的 brk(2)
机制分配空间)。
以下是相关的 Fortran 代码:
double precision u(5,20,20,20)
common /a/ u
gfortran
生成的 GNU 汇编指令是:
.comm a_,320000,32
它声明了一个名为 a_
的通用符号,该符号大小为 320000 字节,并且应在 32 字节边界上对齐。当链接器看到此声明且没有 a_
的其他定义时,它会在 .bss 中为其保留空间,从在生成的二进制文件上运行 objdump
可以清楚地看到这一点:
Sections:
Idx Name Size VMA LMA File off Algn
...
22 .data 00000010 0000000000600b40 0000000000600b40 00000b40 2**3
CONTENTS, ALLOC, LOAD, DATA
23 .bss 0004e220 0000000000600b60 0000000000600b60 00000b50 2**5
ALLOC
...
这里的 .bss 是 320000 (0x4e200) 字节加上一些 32 字节的附加数据。它仅被标记为可分配,仅此而已 - 没有从文件中预填充任何数据。您还可以推断出 32 字节的附加数据位于 a_
之前,因为 u
从 VMA 0x600b80 开始:
(gdb) info address u
Symbol "u" is static storage at address 0x600b80.
(gdb) info symbol &u
a_ in section .bss of /path/to/a.out
u
实际上只是 Fortran 主函数中局部变量的符号,而 a_
是全局可见的存储。这就是为什么您可以在不同的子例程/函数中对数组进行不同的命名,但如果将它们放在适当的公共(public) block 中,仍然可以访问相同的内存。
看起来 .bss 的尴尬 VMA 是 ELF 文件中 .data 段偏移的结果,因为 .bss 紧邻内存中 .data 段之后。 Linux 中加载 .data 段的方式是使用 MAP_PRIVATE
从文件中进行 mmap(2)
编辑,这为映射提供了写时复制语义:
00400000-00401000 r-xp 00000000 00:1d 25681168 /path/to/a.out
00600000-00601000 rw-p 00000000 00:1d 25681168 /path/to/a.out <-- .data
00601000-00670000 rw-p 00000000 00:00 0 [heap]
.bss 与 .data 映射在同一页面中启动,这是有意义的,因为两者都保存读/写数据并且预计将被写入,并且通过不在单独的页面上启动 .bss 可以节省一些 VM。
.data 段之后的所有内容都没有由文件映射备份,因此属于可动态调整的空间,该空间在 /proc/pid/maps< 中以
。该空间以及堆本身是通过使用 [heap]
形式可见brk(2)
移动数据段的末尾(即所谓的程序中断)来控制的。内核中的 ELF 加载程序最初将程序中断移动得足够远,以便为 .bss 保留空间,如可执行文件的 strace
所示:
execve("./a.out", ["a.out"], [/* 230 vars */]) = 0
brk(0) = 0x64f000 <-- already moved past the .bss
我们知道.data段从00600000开始。.bss从00600B60开始。公共(public) block 分配在 0x600b80,其大小为 0x4e200,因此它以 0x64ed80 结束,向上舍入到页边界给出 0x64f000。如果没有其他动态链接库自行分配空间,则真正的程序堆将从此处开始。
由于动态内存分配器 malloc(3)
使用相同的 brk(2)
机制(或者对于大型内存分配器使用匿名 mmap(2)
分配或当数据段大小的限制耗尽时)数组是否位于 .bss 中或使用 ALLOCATE()
分配实际上并不重要。不同之处在于 .bss 最初用零填充,而由 malloc
或 ALLOCATE()
分配的内存内容保持原样。
关于c - Fortran 77 如何分配公共(public) block 变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10291609/
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: When should [assembly: InternalsVisibleTo()] be used?
问题与微服务有关,当我有多个微服务提供将被订购和计费的功能/服务时。 我正在确定采用哪种方法, a) 每个可计费微服务有一个订单和一个计费服务,有各自的数据库。b) 跨所有微服务的通用订单管理和计费服
我正在尝试使用 gcloud图书馆。 (ns firengine.state (:import [com.google.cloud AuthCredentials] [com.goog
Java 允许定义以下一对类。 class Class1 { ... } public Class2 { public Class2(Class1 c1) { ... } } 如果因为 Class1
我正在尝试查找文件 1 和文件 2 中的共同行。如果公共(public)行存在,我想写入文件 2 中的行,否则打印文件 1 中的非公共(public)行。fin1 和 fin2 是这里的文件句柄。它读
好吧,这是一个满口的标题。不过,这让我明白了。这是我的代码的要点,在 jar 里: public class NetworkShared { public static class Login
我在使用 ltree 时遇到 PHP 问题来自 PostgreSQL .我在 SQL 中这样做: SELECT * FROM tabla t WHERE t.parent_path " for "OP
我知道如何为类/接口(interface)/包的子集生成 Javadoc。但是有没有办法只为公共(public)方法的一个子集生成 Javadoc? 我更喜欢能够将方法(Javadoc 标记或注释)标
这个问题在这里已经有了答案: 关闭 12 年前。 Possible Duplicates: c#: why have empty get set properties instead of usin
在我们的每个项目中,都有一个文件用于存储该项目中使用的各种SQL 语句。类的声明方式和字符串的声明方式有一些变化。 示例类声明: internal sealed class ClassName int
我根据 http://docs.jquery.com/Plugins/Authoring 定义了我的插件 (function( $ ){ var methods = { init : fu
我正在使用 Inno Setup 来构建我的安装程序,我有 C:\Users\Public文件夹硬编码在我的 [Files] 中放置一些文件的部分(Inno Setup 没有此文件夹的常量) 我的目标
我有一个 dataframe1 包含像 'ID', 'A', 'B', 'C', 'D', 'E', 'F', 'G' 这样的列. 现在,我创建了两个数据框, dataframe2 包含 'ID',
我有一个抽象类,不幸的是我无法更改它的定义,它基本上提供了一个抽象方法,有点像。 public abstract void do(Data someData, BaseInterface interf
我刚刚在重构时偶然发现了一段奇怪的代码。它看起来像是分解出两个 readString() 方法的共同部分的候选者,只是它似乎是不可能的(这对我来说是一个令人毛骨悚然的脑筋急转弯): private f
是否有解析为公用文件夹的属性?显然,我不想在目录结构中对“c:\users\public”进行硬编码,但我找不到预定义的 Property解决这个问题。是否有一种可接受的方式来指定要在此处安装和/或在
我试图将值从一个类传递到另一个类。 subPanel1 类读取全局变量,但当我通过调整监听器更新这些变量时,它不会更改值。我试图将 rc、gc 和 bc 变量从 subPanel2 类传递到 subP
我想使用具有自动属性的干净且编码较少的类。所有属性(property)都是公共(public)的。在同一类的方法中我也使用了该属性。因此,我认为这种方法是可混搭的,因为我将公共(public)属性用于
不久前,我在 Android 应用程序中创建了一个 SQLiteHelper 类。我不是 100% 确定原因,但表名和列名是嵌套公共(public)静态抽象类中的公共(public)静态最终字段。我记
这个问题已经有答案了: Cannot make a static reference to the non-static method (8 个回答) 已关闭 3 年前。 我正在为类(class)做一
我是一名优秀的程序员,十分优秀!