3

我正在尝试从以下链接编译代码以在生成信号时打印回溯:

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

谢谢你,艾哈迈德。

4

3 回答 3

3

弄清楚了。ucontext.h 包含在 signal.h 中,并且由于包含时间未定义 __USE_GNU,因此未定义 REG_RIP。在我的 C 文件中添加#include <ucontext.h>没有效果。

#include <stdio.h>解决问题后立即添加“#define __USE_GNU”行。

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

在 stdio.h 之前添加 #define 无济于事,因为 stdio.h 包含 features.h 而 undef __USE_GNU

感谢大家的帮助。

于 2013-05-23T01:25:19.107 回答
1

我怀疑其他东西是#includesys/ucontext.h在你开始之前#include

头文件 ( #ifndef _SYS_UCONTEXT_H, #define _SYS_UCONTEXT_H) 中的保护可防止头文件被 #include 多次。如果此文件已包含在您的 之前#define __USE_GNU,它将无效。

如果您将您的移动#define到 C 文件的顶部,它会编译吗?

于 2013-05-23T00:30:57.340 回答
0

signal.h之前包含在您的主模块中(在您定义 __USE_GNU 之前)这是问题所在吗?

如果将#define 移到主文件的开头会怎样?

另外,关于自己定义 __USE_GNU:

_GNU_SOURCE 和 __USE_GNU

于 2013-05-23T00:30:45.823 回答