Что вызывает у меня ошибку сегментации (ядро сброшено) - PullRequest
2 голосов
/ 25 марта 2019

Я читаю книгу о кодировании операционной системы и пишу примеры кода на 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;
}

1 Ответ

2 голосов
/ 25 марта 2019

Не думаю, что вы должны добавлять массивы в раздел (в этом примере вы ошиблись, дважды инициализируя .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

...