【问题标题】:Retrieving sigcontext during backtrace在回溯期间检索 sigcontext
【发布时间】:2023-04-07 04:35:01
【问题描述】:

在编写一些用 C++ 打印回溯的代码时,我遇到了this answer,其中包括复制类型的定义:

/* 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;

我不能只包含<asm/ucontext.h>,因为它被简单地定义为ucontext,它与<sys/ucontext.h> 中类似命名的类型发生冲突(包含在必要的<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;

我在这里只需要asm 版本中的struct sigcontext uc_mcontext 成员。有没有比复制这个结构更好的方法来检索该值?对我来说,这似乎令人难以置信的骇人听闻且容易出错。

【问题讨论】:

    标签: c++ gcc backtrace


    【解决方案1】:

    一种可能的解决方法是使asm/ucontext.h 成为源文件中的第一个包含并滥用预处理器来重命名冲突的定义:

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

    然后您可以使用asm_ucontext 来引用ucontext 的替代定义。

    使用 sed 自动从系统文件中提取必要的定义是一种不那么 hacky 的方法:

    $ 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;
    };
    

    【讨论】:

    • “不那么老套的方法”是的,好吧。
    • @Andrew 不要让我开始通过 sed 修补程序集来解决编译器错误)
    猜你喜欢
    • 2013-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-23
    • 2021-10-29
    • 2013-07-20
    相关资源
    最近更新 更多