This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: Failure to recognize siginfo_t._sifields
- From: Cedric Roux <cedric dot roux at acri-st dot fr>
- To: Amittai Aviram <amittai dot aviram at yale dot edu>
- Cc: gcc-help at gcc dot gnu dot org
- Date: Thu, 25 Nov 2010 09:28:15 +0100
- Subject: Re: Failure to recognize siginfo_t._sifields
- References: <2A0FDA3F-27A1-4783-9DFE-BDBFCFE2C219@yale.edu>
On 11/24/2010 09:20 PM, Amittai Aviram wrote:
This question lies somewhere between GCC and glibc, so I hope it's OK if I start here.
I have a signal handler for SIGSEGV
void handle_segfault(int signo, siginfo_t * siginfo, void * ucontext);
which changes the permissions on the page to which access has provoked the SIGSEGV as part of a copy-on-write scheme, and I am investigating a case where the address appears to be wrong. (The access is to the heap—more below.) My code gets the address of the access from siginfo->si_addr. When debugging, GDB reported that siginfo_t has no such member as si_addr, so I found out, by looking at the definition of siginfo_t in my /usr/include/bits/siginfo.h (#included in /usr/include/signal.h), that the real name of the field is
siginfo_t._sifields._sigfault.si_addr
for which there is a #define statement below the definition of siginfo_t:
#define si_addr _sifields._sigfault.si_addr
I can query GDB for the value under this name, and I get the _correct_ address. However, if I try to change my source code so that, instead of using siginfo->si_addr, it uses siginfo->_sifields._sigfault.si_addr, I get this from GCC:
error: ‘struct<anonymous>’ has no member named ‘_sifields’
The questions pertaining to GCC are:
1. Why doesn't GCC accept the "real" name as equivalent to the #defined alias?
2. Why, when it refuses, does it call siginfo_t "struct<anonymous>," when siginfo.h defines the type thus?—
because "si_addr" is extended to "_sifields._sigfault.si_addr"
so you write "siginfo->_sifields._sigfault.si_addr"
and the C preprocessor spits "siginfo->_sifields._sigfault._sifields._sigfault.si_addr"
that works:
/home/cro> cat a.c
#include <signal.h>
#undef si_addr
int main(void)
{
siginfo_t t;
t._sifields._sigfault.si_addr = 0;
return 0;
}
but you don't want to do that I guess.