C++ SymGetLineFromAddr 有错误代码 126
C++ SymGetLineFromAddr has error code 126
我围绕一些 WINAPI 函数编写了一个包装器。但是,SymGetLineFromAddr
总是失败并出现错误 126。经过一些研究,似乎是因为 SymInitalize
没有被调用或失败。调试显示 SymInitalize
实际上并没有失败。更令人困惑的是 SymFromAddr
工作得很好。那么为什么 SymGetLineFromAddr
总是以代码 126 失败?
class debug_state
{
// held for caching
SYMBOL_INFO* symbol;
IMAGEHLP_LINE* line;
HANDLE process;
bool is_init = false;
public:
static constexpr int MAX_LEN = 1024;
inline void init()
{
if (is_init)
return;
process = GetCurrentProcess();
SymInitialize(process, NULL, TRUE);
symbol = (SYMBOL_INFO*)calloc(sizeof(SYMBOL_INFO) + MAX_LEN, 1);
symbol->MaxNameLen = MAX_LEN;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
line = (IMAGEHLP_LINE*)malloc(sizeof(IMAGEHLP_LINE));
line->SizeOfStruct = sizeof(IMAGEHLP_LINE);
is_init = true;
}
inline SYMBOL_INFO* get_info_of(intptr_t ptr)
{
init();
SymFromAddr(process, (DWORD64)(ptr), 0, symbol);
return symbol;
}
inline IMAGEHLP_LINE* get_line_of(intptr_t ptr)
{
init();
DWORD tmp;
if (!SymGetLineFromAddr(process, (DWORD)(ptr), &tmp, line))
{
DWORD d = GetLastError();
std::cout << d;
}
return line;
}
};
SymFromAddr
works perfectly fine.
之所以有效,是因为它不会截断其指针参数:
SymFromAddr(process, (DWORD64)(ptr), 0, symbol);
// ^^^^^^^^^ preserves 64 bits of information
对比 SymGetLineFromAddr
的调用:
SymGetLineFromAddr(process, (DWORD)(ptr), &tmp, line)
// ^^^^^^^ truncate to 32 bits
这只会将指针值的低 32 位传递给 API 调用。只要您将它与 32 位进程一起使用,它就可以工作。对于 64 位进程,信息的上半部分丢失了。你应该改用这个:
SymGetLineFromAddr(process, (DWORD64)(ptr), &tmp, line)
我围绕一些 WINAPI 函数编写了一个包装器。但是,SymGetLineFromAddr
总是失败并出现错误 126。经过一些研究,似乎是因为 SymInitalize
没有被调用或失败。调试显示 SymInitalize
实际上并没有失败。更令人困惑的是 SymFromAddr
工作得很好。那么为什么 SymGetLineFromAddr
总是以代码 126 失败?
class debug_state
{
// held for caching
SYMBOL_INFO* symbol;
IMAGEHLP_LINE* line;
HANDLE process;
bool is_init = false;
public:
static constexpr int MAX_LEN = 1024;
inline void init()
{
if (is_init)
return;
process = GetCurrentProcess();
SymInitialize(process, NULL, TRUE);
symbol = (SYMBOL_INFO*)calloc(sizeof(SYMBOL_INFO) + MAX_LEN, 1);
symbol->MaxNameLen = MAX_LEN;
symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
line = (IMAGEHLP_LINE*)malloc(sizeof(IMAGEHLP_LINE));
line->SizeOfStruct = sizeof(IMAGEHLP_LINE);
is_init = true;
}
inline SYMBOL_INFO* get_info_of(intptr_t ptr)
{
init();
SymFromAddr(process, (DWORD64)(ptr), 0, symbol);
return symbol;
}
inline IMAGEHLP_LINE* get_line_of(intptr_t ptr)
{
init();
DWORD tmp;
if (!SymGetLineFromAddr(process, (DWORD)(ptr), &tmp, line))
{
DWORD d = GetLastError();
std::cout << d;
}
return line;
}
};
SymFromAddr
works perfectly fine.
之所以有效,是因为它不会截断其指针参数:
SymFromAddr(process, (DWORD64)(ptr), 0, symbol);
// ^^^^^^^^^ preserves 64 bits of information
对比 SymGetLineFromAddr
的调用:
SymGetLineFromAddr(process, (DWORD)(ptr), &tmp, line)
// ^^^^^^^ truncate to 32 bits
这只会将指针值的低 32 位传递给 API 调用。只要您将它与 32 位进程一起使用,它就可以工作。对于 64 位进程,信息的上半部分丢失了。你应该改用这个:
SymGetLineFromAddr(process, (DWORD64)(ptr), &tmp, line)