2013-05-23 3 views
2

Я пытаюсь скомпилировать код по следующей ссылке, чтобы распечатать трассировку, когда генерируется сигнал:#define не распространяющихся в заголовочном файле C

http://www.linuxjournal.com/article/6391?page=0,1 (из статьи http://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/063/6391/6391l3.html)

я сделал необходимые изменения (REG_EIP -> REG_RIP). Я также изменил «#include <ucontext.h>» на «#include <sys/ucontext.h>», чтобы отладить мою проблему, которую я объясню ниже.

В верхней части файла выглядит следующим образом:

#include <stdio.h> 
#include <stdlib.h> 
#include <signal.h> 
#include <execinfo.h> 

/* get REG_EIP from ucontext.h */ 
#define __USE_GNU 
#include <sys/ucontext.h> 

... 

С кодом, как есть, я получаю следующее сообщение об ошибке:

# gcc ./st2.c -rdynamic -o st2 
./st2.c: In function ‘bt_sighandler’: 
./st2.c:22: error: ‘REG_RIP’ undeclared (first use in this function) 
./st2.c:22: error: (Each undeclared identifier is reported only once 
./st2.c:22: error: for each function it appears in.) 

Однако, когда я скопировать строку «#define __USE_GNU "на вершине„/usr/include/sys/ucontext.h“(который я знаю, это очень плохая идея, и носит лишь временный характер) следующим образом:

#ifndef _SYS_UCONTEXT_H                
#define _SYS_UCONTEXT_H 1 

#define __USE_GNU 
#include <features.h> 
#include <signal.h>                 
#include <bits/wordsize.h> 

............ 

#endif // _SYS_UCONTEXT_H 

Моя программа скомпилирована и работает правильно.

Я сбив с толку, почему #define в моей программе не «течет» в заголовочный файл «sys/ucontext.h», а добавляет #define непосредственно в sys/ucontext.h, имеет значение. Любая помощь была бы очень оценена. J

Спасибо, Ahmed.

+0

__USE_GNU - внутренний макрос glibc, который не должен определяться непосредственно вашим приложением. –

+0

@jwodder Не могли бы вы описать, что вы редактировали, чтобы исправить строку "#include" в моем исходном сообщении. Спасибо. –

+0

@AhmedA: Я просто поместил строки внутри backticks (\ '), чтобы включить форматирование кода и предотвратить использование SO для обработки заголовков как HTML-тегов. – jwodder

ответ

3

Выяснил это. ucontext.h включен из signal.h, а поскольку __USE_GNU не определяется временем включения, REG_RIP не определяется. Выполнение добавления #include <ucontext.h> в моем файле C не повлияло.

Добавление строки «#define __USE_GNU» сразу после #include <stdio.h> решило проблему.

#include <stdio.h> 
#define __USE_GNU 
#include <stdlib.h> 
#include <signal.h> 
#include <execinfo.h> 

Добавление #define перед тем stdio.h не поможет, так как stdio.h включает features.h, которые UNDEF __USE_GNU

Спасибо всем за вашу помощь.

+0

Я предполагаю, что это одна из причин, почему вы не должны использовать __USE_GNU. (См. Ссылку в ответе @ FogleBird.) – MatthewD

+0

Обычно лучше всего включить в начало кода такой '# define' (как' __USE_GNU'). Определения, такие как '_XOPEN_SOURCE 800', должны предшествовать первому системному заголовку на которые может повлиять или отсутствие определения. Кроме того, gcc -H может быть полезным; он перечисляет заголовки, включенные в заказ, включенный с индикатором «глубина включения». –

0

signal.h включен ранее в ваш основной модуль (прежде чем вы определяете __USE_GNU). Это проблема?

Что делать, если вы переместите #define в начало основного файла?

Кроме того, относительно определения __USE_GNU себя:

_GNU_SOURCE and __USE_GNU

+0

См. Мой комментарий выше относительно перемещения #define в начало файла. Добавление обоих файлов #deifne - __USE_GNU и __GNU_SOURCE в мой файл C не помогло. –

+0

@AhmedA Это опечатка здесь? Это '_GNU_SOURCE' только с одним лидирующим подчеркиванием. И это должно быть определено до того, как заголовок glibc будет включен, лучше всего в командной строке ('-D_GNU_SOURCE'). –

+0

Это была опечатка, извините. Я использовал _GNU_SOURCE. По вашему предложению я попытался передать его как вариант компиляции, получить другую ошибку компиляции: # gcc -D_GNU_SOURCE ./st2.c -rdynamic -o st2 ./st2.c:7:1: предупреждение: «__USE_GNU» переопределено В файле, включенном в /usr/include/stdio.h:28, из ./st2.c:1: /usr/include/features.h:303:1: предупреждение: это местоположение предыдущего определения –

1

Я подозреваю, что-то еще #including sys/ucontext.h перед вашим #include получает к нему.

Защита в файле заголовка (#ifndef _SYS_UCONTEXT_H, #define _SYS_UCONTEXT_H) не позволяет заголовочному файлу быть # включенным несколько раз. Если этот файл уже был включен до вашего #define __USE_GNU, он не будет иметь никакого эффекта.

Состоит ли, если вы переместите свой #define в начало своего C-файла?

+0

Перемещение #define в начало моего C-файла (и удаление строки, добавленной в sys/ucontext.h, не имело никакого эффекта. Такая же ошибка компиляции. –