【问题标题】:Name of a function defined in executable (using dladdr)可执行文件中定义的函数的名称(使用 dladdr)
【发布时间】:2019-03-25 12:36:43
【问题描述】:

我有一个程序(应用程序,而不是共享库):

void func() {
    int RESULT = UNW_ESUCCESS;
    unw_context_t context;
    unw_getcontext(&context);

    unw_cursor_t cursor;
    RESULT = unw_init_local(&cursor, &context);
    assert(RESULT == UNW_ESUCCESS);

    const int BUFFER_SIZE = 512;
    char functionName[BUFFER_SIZE] = {"<unknown>"};
    unw_word_t offset;
    RESULT = unw_get_proc_name(&cursor, functionName, BUFFER_SIZE, &offset);
}

int main() {
    func();
}

我希望 functionName 为“func”——我从中调用 unw_get_proc_name() 的函数的名称。但是 unw_get_proc_name() 失败了。我调试了一下,发现它使用函数 dladdr() 来获取函数的名称:

Dl_info dyldInfo;
if (dladdr((void *)addr, &dyldInfo)) {
    if (dyldInfo.dli_sname != NULL) {
      snprintf(buf, bufLen, "%s", dyldInfo.dli_sname);
      *offset = (addr - (pint_t) dyldInfo.dli_saddr);
      return true;
    }
  }

由于某种原因,dyldInfo.dli_sname 为 0。为什么?我该如何解决这个问题?

我还使用了来自共享库的函数 unw_get_proc_name(),在这种情况下它成功了。所以问题是为什么在从应用程序(不是共享库)调用时检索函数名(上面程序中的“func”)失败?我该如何解决?

我尝试将属性 __attribute__((noinline)) 和 __attribute__((visibility("default"))) 添加到我的 func() 函数,但没有帮助。

【问题讨论】:

    标签: c++ linux dll symbol-table dladdr


    【解决方案1】:

    我对@9​​87654321@ 的解读是它只能定位位于共享对象(即共享库)中的符号。相关部分为(强调我的):

    函数 dladdr() 确定 addr 中指定的地址是否位于调用应用程序加载的共享对象之一中。

    但是,我发现this link 表明与-Wl,-E 链接可能会有所帮助,因此您可以尝试一下。

    【讨论】:

    • 非常感谢!这样可行!但问题是返回名称被破坏了。是否有可能(以编程方式)解开它?
    • 显然可以拨打abi::__cxa_demangle,如here所述
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-07-05
    • 2013-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多