_dl_runtime_resolve() 中的分段错误

Posted

技术标签:

【中文标题】_dl_runtime_resolve() 中的分段错误【英文标题】:Segmentation fault in _dl_runtime_resolve() 【发布时间】:2012-05-21 15:23:34 【问题描述】:

我在遇到分段错误的代码中执行简单的字符串操作。我不知道确切的问题是什么。 请看看是否有人可以提供帮助。

核心的回溯是

(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);
            
        
     

【问题讨论】:

它在什么操作系统上运行?您正在使用哪些编译选项? 【参考方案1】:

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

两个最常见的原因是:

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

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

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

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

【讨论】:

【参考方案2】:

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

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

第二次函数调用是:

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

【讨论】:

“这是 GOT 表的问题”——你可能是对的,也可能是错的(_dl_runtime_resolve 中的崩溃还有许多其他可能的原因)。您没有提供任何证据来支持您的主张,而且您对惰性 PLT 解决过程中实际发生的情况的描述在许多细节上都是错误的,对于不熟悉它的任何人来说都是没有意义的。【参考方案3】:

我在这里看到内存泄漏:

当你这样做时,你基本上会丢失你以前的字符串LdapDN

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

【讨论】:

以上是关于_dl_runtime_resolve() 中的分段错误的主要内容,如果未能解决你的问题,请参考以下文章

[ctf wiki pwn] stackoverflow:ret2dlresolve系列2(_dl_runtime_resolve glibc源码解析实践)

Python中的分页管理

刷新 UITableView 中的分页数据

如何在symfony和doctrine中使用mysql视图表中的分页?

Django中的分页

如何在swift 3中的表视图单元格中实现集合视图的分页?