_dl_runtime_resolve() 中的分段错误

Segmentation fault in _dl_runtime_resolve()

本文关键字:分段 错误 dl runtime resolve      更新时间:2023-10-16

我在代码中执行简单的字符串操作,其中出现分段错误。我无法理解确切的问题是什么。请看一下是否有人可以提供帮助。

核心的回溯是

(gdb) bt
#0  0x00007f595dee41da in _dl_fixup () from /lib64/ld-linux-x86-64.so.2
#1  0x00007f595deea105 in _dl_runtime_resolve () from /lib64/ld-linux-x86-64.so.2
#2  0x0000000000401d04 in getNodeInfo (node=0x7fffbfb4ba83 "TCU-0")
    at hwdetails.cpp:294
#3  0x0000000000402178 in main (argc=3, argv=0x7fffbfb4aef8)
    at hwdetails.cpp:369

在第 294 行,崩溃即将到来,cout声明在那里。
LdapDNchar *的,不是NULL.

if ( Epath && (Epath->Entry[0].EntityType == SAHPI_ENT_UNSPECIFIED ||
         Epath->Entry[0].EntityType == SAHPI_ENT_ROOT )) {
        // nothing is mapped. Degrade the ldap dn path to slot.
        if(LdapDN){
            std::cout << "LdapDN " << LdapDN << std::endl;
        }
        std::string ldapDN;
        ldapDN = LdapDN;
        std::string slot = LDAP_PIU_ID;
        if ( ldapDN.compare(0, slot.length(), slot) != 0 ) {
            size_t pos = ldapDN.find(slot);
            if ( pos != std::string::npos ) {
                ldapDN = ldapDN.substr(pos);
                LdapDN = (char *)ldapDN.c_str();
                //getEntityPathFromLdapDn(ldapDN.c_str(), epath, domid);
            }
        }
     }

_dl_fixup中的崩溃通常意味着您已经损坏了运行时加载程序的状态。

最常见的两个原因是:

  1. 堆损坏(溢出)或
  2. glibc本身的不匹配部分。

如果您没有设置例如 LD_LIBRARY_PATH指向一个非标准glibc,那么我们可以忘记原因#2。

对于#1,在Valgrind下运行程序,并确保它没有检测到错误。

如果实际上没有,请使用 disasinfo registers GDB 命令,使用它们的输出更新您的问题,您可能会收到其他帮助。

这是GOT表的问题。 _dl_runtime_resolve - 当动态库调用某些函数时更改 GOT(全局偏移表)的过程。下次使用更改的GOT条目。当来自动态库的函数(例如来自 libc.so 的 printf())首次在代码中调用时:

  1. 转到 PLT(程序查找表)。PLT 是一个蹦床,它从 GOT 获取被调用函数的正确地址。
  2. 从 PLT 转到 GOT
  3. 返回PLT
  4. 呼叫_dl_runtime_resolve
    • 将实际函数跳转地址存储到 GOT
    • 从动态库调用函数

第二次函数调用是:

  1. 转到 PLT
  2. 转到 GOT
  3. GOT可以从动态库直接跳转到函数地址。GOT是对再次调用的函数的引用,而无需快速通过_dl_runtime_resolve。

我在这里看到内存泄漏:

你基本上失去了你以前的字符串LdapDN当你这样做时

 if ( pos != std::string::npos ) {
            ldapDN = ldapDN.substr(pos);
            LdapDN = (char *)ldapDN.c_str();
            //getEntityPathFromLdapDn(ldapDN.c_str(), epath, domid);
        }