5

我正在阅读Itanium ABI,它说

当且仅当指针相等时,两个 type_info 指针才指向等价的类型描述。实现必须满足这个约束,例如通过使用符号抢占、COMDAT 部分或其他机制。

有谁知道在使用动态加载库时如何在流行平台上实现这一点的血腥细节,例如使用 GCC 和 GNU binutils 的 Linux?它有多可靠?

此外,我的印象是typeidMSVC 中的比较是(曾经?)使用运行时字符串比较对损坏的符号名称实现的,因为不能保证满足这一要求。这仍然是它的做法吗?是否存在阻止 MSVC 使用与 Itanium ABI 平台相同的技术的技术平台限制?

编辑还有一个问题:跨模块边界(在任一 ABI 中)捕获异常是否也依赖于 RTTI 信息,或者除了等效于 runtime 之外是否还涉及另一种机制dynamic_cast

4

1 回答 1

2

MSVC 首先使用指针比较,然后,如果失败,则比较字符串。可以在 VS2012 的 CRT 源码中看到实现:

extern "C" _CRTIMP int __cdecl __TypeMatch(
    HandlerType *pCatch,                // Type of the 'catch' clause
    CatchableType *pCatchable,          // Type conversion under consideration
    ThrowInfo *pThrow                   // General information about the thrown
                                        //   type.
) {
    // First, check for match with ellipsis:
    if (HT_IS_TYPE_ELLIPSIS(*pCatch)) {
        return TRUE;
    }

    // Not ellipsis; the basic types match if it's the same record *or* the
    // names are identical.
    if (HT_PTD(*pCatch) != CT_PTD(*pCatchable)
      && strcmp(HT_NAME(*pCatch), CT_NAME(*pCatchable)) != 0) {
        return FALSE;
    }
    ...

Itanium ABI 始终只使用指针比较。它应该与 DLL 一起工作的方式是动态加载程序应确保程序地址空间中的每个异常都有一个 typeinfo 对象的实例。

如果您对异常 RTTI 的实际实现和捕获信息感兴趣,请查看我的OpenRCE 文章(MSVC) 和Recon 2012 演示文稿(GCC,MSVC x64)。

于 2014-02-25T14:14:23.787 回答