Barry
Barry

Reputation: 303397

Retrieving sigcontext during backtrace

In writing some code to print backtraces in C++, I came across this answer, which includes copying the definition of a type:

/* This structure mirrors the one found in /usr/include/asm/ucontext.h */
typedef struct _sig_ucontext {
 unsigned long     uc_flags;
 struct ucontext   *uc_link;
 stack_t           uc_stack;
 struct sigcontext uc_mcontext;
 sigset_t          uc_sigmask;
} sig_ucontext_t;

I can't just include <asm/ucontext.h> since there it is defined as simply ucontext which collides with a similarly named type from <sys/ucontext.h> (which is included from the necessary <signal.h>):

/* Userlevel context.  */
typedef struct ucontext
  {
    unsigned long int uc_flags;
    struct ucontext *uc_link;
    stack_t uc_stack;
    mcontext_t uc_mcontext;
    __sigset_t uc_sigmask;
    struct _libc_fpstate __fpregs_mem;
  } ucontext_t;

All I need here is the struct sigcontext uc_mcontext member from the asm version. Is there a better way to retrieve that value than just copying out this struct? That seems incredibly hackish and error-prone to me.

Upvotes: 3

Views: 1494

Answers (1)

yugr
yugr

Reputation: 21955

One potential workaround is to make asm/ucontext.h the first include in your source file and abuse preprocessor to rename conflicting definition:

#define ucontext asm_ucontext
#include <asm/ucontext.h>
#undef asm_ucontext

You can then use asm_ucontext to refer to alternative definition of ucontext.

A bit less hacky approach is to employ sed to automatically extract necessary definitions from system file:

$ echo '#include <asm/ucontext.h>' | gcc -x c - -E -o- | sed -n '/^struct ucontext/,/^};/{ s/ucontext/asm_ucontext/; p}' | tee asm_ucontext.h
struct asm_ucontext {
  unsigned long uc_flags;
  struct asm_ucontext *uc_link;
  stack_t uc_stack;
  struct sigcontext uc_mcontext;
  sigset_t uc_sigmask;
};

Upvotes: 1

Related Questions