【问题标题】:What is causing me to get a Segmentation fault (core dumped)是什么导致我出现分段错误(核心转储)
【发布时间】:2019-03-24 21:57:33
【问题描述】:

我正在阅读一本关于编写操作系统的书,我正在编写书中的 C 代码示例,并在终端中编译和测试代码,但我遇到了这段代码的问题。

包含此代码的文件名为“hello.c”。 我用“gcc hello.c -o hello”编译了文件 然后用“./hello”运行它。

我收到消息分段错误(核心转储), 而且我不确定自己做错了什么。

#include <stdio.h>

void preinit1() {
  printf("%s\n", __FUNCTION__);
}

void preinit2() {
  printf("%s\n", __FUNCTION__);
}

void init1() {
  printf("%s\n", __FUNCTION__);
}

void init2() {
  printf("%s\n", __FUNCTION__);
}

typedef void (*preinit)();
typedef void (*init)();

__attribute__((section(".init_array"))) preinit
  preinit_arr[2] = {preinit1, preinit2};

__attribute__((section(".init_array"))) init
  init_arr[2] = {init1, init2};

int main(int argc, char *argv[])
{
    printf("hello world!\n");

    return 0;
}

【问题讨论】:

标签: c linux fault


【解决方案1】:

我认为您不应该将数组添加到该部分(示例中存在错误,初始化 .init_array 两次)。

__attribute__((section(".preinit_array"))) preinit preinit_arr1 = preinit1;
__attribute__((section(".preinit_array"))) preinit preinit_arr2 = preinit2;

__attribute__((section(".init_array"))) init init_arr1 = init1;
__attribute__((section(".init_array"))) init init_arr2 = init2;

这是使用数组声明的部分

objdump -s -j .init_array hello.orig 

hello.orig:     file format elf64-x86-64

Contents of section .init_array:
 3dc0 30110000 00000000 00000000 00000000  0...............
 3dd0 35110000 00000000 48110000 00000000  5.......H.......
 3de0 5b110000 00000000 6e110000 00000000  [.......n.......

这是有效的部分

objdump -s -j .init_array hello

hello:     file format elf64-x86-64

Contents of section .init_array:
 3dc8 30110000 00000000 35110000 00000000  0.......5.......
 3dd8 48110000 00000000 5b110000 00000000  H.......[.......
 3de8 6e110000 00000000                    n.......

在前者中,3dc8 处的空指针可能导致分段(见下文),我不知道为什么其他人可以解释。

(gdb) bt
#0  0x0000000000000000 in ?? ()
#1  0x00005555555551f5 in __libc_csu_init ()
#2  0x00007ffff7dec02a in __libc_start_main (main=0x555555555181 <main>, argc=1, argv=0x7fffffffe1f8, init=0x5555555551b0 <__libc_csu_init>, 
    fini=<optimized out>, rtld_fini=<optimized out>, stack_end=0x7fffffffe1e8) at ../csu/libc-start.c:264
#3  0x000055555555507a in _start ()

仅修复关于 .preinit_array 的拼写错误,使 preinit 调用有效,但 init 无效

【讨论】:

  • 从数组中更改这些有效。我不知道为什么它们在书中将其作为数组保存,但是当我更改它们时,我得到的输出与书中显示的相同。谢谢。
  • 奇怪,书籍示例应该可以工作,也许 gcc 以及它如何在部分中布局数组的方式有所改变
  • 我只是想了想你说的话,又看了一遍书。他们在本书代码中显示您应该将数组添加到 .init_array 部分,但在他们说要使用 .preinit_array 部分的代码之前。所以这是一本书的错字,但如果没有你提到无法将数组添加到该部分,我不会注意到。)
猜你喜欢
  • 2019-08-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多