3

I am trying to compile the code from the following link to print the backtrace when a signal is generated:

http://www.linuxjournal.com/article/6391?page=0,1 (from article http://www.linuxjournal.com/files/linuxjournal.com/linuxjournal/articles/063/6391/6391l3.html)

I made the necessary changes (REG_EIP -> REG_RIP). I also changed "#include <ucontext.h>" to "#include <sys/ucontext.h>" to debug my issue which I will explain below.

The top of the file is as follows:

#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>

...

With the code as is, I get the following error:

# 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.)

However, when I copy the line "#define __USE_GNU" to the top of "/usr/include/sys/ucontext.h" (which I know is a very bad idea and is only temporary) as follows:

#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

My program compiles and run correctly.

I am baffled why the #define in my program does not "flow" into the header file "sys/ucontext.h", and adding #define directly into sys/ucontext.h makes a difference. Any help would be very appreciated.j

Thank you, Ahmed.

umlcat
  • 4,091
  • 3
  • 19
  • 29
Ahmed A
  • 3,362
  • 7
  • 39
  • 57
  • __USE_GNU is a glibc internal macro that shouldn't be ever defined directly by your application. – Bjoern Rennhak May 23 '13 at 00:32
  • @jwodder Can you please describe what editing you did to fix the "#include" string in my original post. Thank you. – Ahmed A May 23 '13 at 01:14
  • @AhmedA: I just put the strings inside backticks (\`) to turn on code formatting and prevent SO from trying to treat the headers as HTML tags. – jwodder May 23 '13 at 01:21

3 Answers3

3

Figured it out. ucontext.h is included from signal.h, and since __USE_GNU is not defined by the inclusion time, REG_RIP does not get defined. Doing an addition #include <ucontext.h> in my C file had no effect.

Adding the line "#define __USE_GNU" right after #include <stdio.h> solved the issue.

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

Adding the #define before stdio.h does not help, as stdio.h includes features.h which undef __USE_GNU

Thanks to everybody for your help.

Ahmed A
  • 3,362
  • 7
  • 39
  • 57
  • I guess that's one of the reasons why you're not supposed to use __USE_GNU. (See the link in @FogleBird's answer.) – MatthewD May 23 '13 at 10:02
  • It's generally best to include such `#define` (as `__USE_GNU`) at the start of the code. Definitions such as `_XOPEN_SOURCE 800` have to precede the first system header that might be affected by the presence or absence of the definition. Also, `gcc -H` can be useful; it lists the headers included in the order included with a 'depth of inclusion' indicator too. – Jonathan Leffler Jan 12 '15 at 20:31
1

I suspect something else is #including sys/ucontext.h before your #include gets to it.

The protection in the header file (#ifndef _SYS_UCONTEXT_H, #define _SYS_UCONTEXT_H) prevents the header file from being #included multiple times. If this file has already been included before your #define __USE_GNU, it will have no effect.

Does it compile if you move your #define to the top of your C file?

MatthewD
  • 2,509
  • 2
  • 23
  • 27
  • Moving the #define to the top of my C file (and remove the a line added to sys/ucontext.h did not have any effect. Same compile error. – Ahmed A May 23 '13 at 00:37
0

signal.h is included earlier in your main module (before you define __USE_GNU) Is this the problem?

What if you move the #define to the beginning of your main file?

Also, regarding defining __USE_GNU yourself:

_GNU_SOURCE and __USE_GNU

Community
  • 1
  • 1
FogleBird
  • 74,300
  • 25
  • 125
  • 131
  • Please see my comment above regarding moving #define to top of file. Adding both the two #deifne - __USE_GNU and __GNU_SOURCE to my C file did not help. – Ahmed A May 23 '13 at 00:43
  • @AhmedA Is that a typo here? It's `_GNU_SOURCE` with only one leading underscore. And that must be defined before any glibc header is included, best on the command line (`-D_GNU_SOURCE`). – Daniel Fischer May 23 '13 at 00:54
  • That was a typo, sorry about that. I used _GNU_SOURCE. Per your suggestion I tried passing it as a compile option, get a different compile error: # gcc -D_GNU_SOURCE ./st2.c -rdynamic -o st2 ./st2.c:7:1: warning: "__USE_GNU" redefined In file included from /usr/include/stdio.h:28, from ./st2.c:1: /usr/include/features.h:303:1: warning: this is the location of the previous definition – Ahmed A May 23 '13 at 01:01