gcc – 在g中使用符号’_end’会导致分段错误

栏目: 服务器 · 编程工具 · 发布时间: 7年前

内容简介:翻译自:https://stackoverflow.com/questions/33760923/using-symbol-end-in-g-leads-to-a-segmentation-fault

考虑以下c源代码:

int _end[1050];

int main() {
    for (int i = 0; i < 1050; i++)
        _end[i] = 0;
    return 0;
}

编译行:g main.cpp -o main -O0

在Ubuntu 14.04下使用gcc-4.8.4和clang-3.6.0时,运行此代码会导致分段错误.奇怪的行为是符号_end指向静态分配的数组_end的末尾,而不是它的开头.如果我们用end_替换_end,一切正常.

此外,如果我们要求gcc通过提供-S命令行参数输出汇编代码,则带有“_end”的版本与具有任何其他数组名称的版本之间没有显着差异:

$g++ main.cpp -o main.s -O0 -S
$g++ main2.cpp -o main2.s -O0 -S
$diff main.s main2.s
1,2c1,2
<   .file   "main.cpp"
<   .globl  _end
---
>   .file   "main2.cpp"
>   .globl  end_
5,7c5,7
<   .type   _end, @object
<   .size   _end, 4200
< _end:
---
>   .type   end_, @object
>   .size   end_, 4200
> end_:
25c25
<   movl    $0, _end(,%rax,4)
---
>   movl    $0, end_(,%rax,4)

但是如果我们使用objdump来转储可执行文件并对它们运行diff,我们将会看到在_end版本中使用的地址比所需的地址多4200 = 4 * 1050字节:

$g++ main.cpp -o main -O0
$g++ main2.cpp -o main2 -O0
$objdump -d main >main.dump
$objdump -d main2 > main2.dump
$diff main.dump main2.dump
2c2
< main:     формат файла elf64-x86-64    // "File format" in Russian
---
> main2:     формат файла elf64-x86-64
123c123
<   4004ff: c7 04 85 c8 20 60 00    movl   $0x0,0x6020c8(,%rax,4)
---
>   4004ff: c7 04 85 60 10 60 00    movl   $0x0,0x601060(,%rax,4)

据我所知,gcc编译器可能会根据需要处理以下划线开头的变量,i.即在代码中使用这些符号是一种不好的做法.但我的问题是:这里到底发生了什么?为什么_end被替换为已分配数组末尾的地址?如果我们使用“-S”命令行参数,为什么没有区别,但创建的二进制文件实际上有区别?在这种情况下,gcc和clang的表现并不一样,这对我来说也很奇怪.

以_开头的标记是保留的,您不应该使用它们.似乎_end是为在 Linux 上编译的程序定义的外部符号,并且表示在未初始化数据段(也称为BSS段)结束之后的第一个地址.

Note: On some systems the names of these symbols are preceded by
underscores, thus: _etext, _edata, and _end.

资料来源: http://man7.org/linux/man-pages/man3/end.3.html

翻译自:https://stackoverflow.com/questions/33760923/using-symbol-end-in-g-leads-to-a-segmentation-fault


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

信息简史

信息简史

[美] 詹姆斯·格雷克 / 高博 / 人民邮电出版社 / 2013-10 / 69.00元

人类与信息遭遇的历史由来已久。詹姆斯•格雷克笔下的这段历史出人意料地从非洲的鼓语讲起(第1章)。非洲土著部落在尚未直接跨越到移动电话之前,曾用鼓声来传递讯息,但他们是如何做到的呢?后续章节进而讲述了这段历史上几个影响深远的关键事件,包括文字的发明(第2章)、罗伯特•考德里的第一本英语词典(第3章)、查尔斯•巴贝奇的差分机与爱达•拜伦的程序(第4章)、沙普兄弟的信号塔与摩尔斯电码(第5章)。 ......一起来看看 《信息简史》 这本书的介绍吧!

html转js在线工具
html转js在线工具

html转js在线工具

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具