我目前正在研究一些日志代码,它们应该 - 除其他外 - 打印有关调用函数的信息.这应该相对容易,标准C++有一个type_info类.它包含typeid'd类/函数/ etc的名称.但它被破坏了.它不是很有用.即typeid(std::vector<int>).name()回归St6vectorIiSaIiEE.
有没有办法从中产生有用的东西?就像std::vector<int>上面的例子一样.如果它只适用于非模板类,那也没关系.
该解决方案应该适用于gcc,但如果我可以移植它会更好.这是为了记录所以它不是那么重要,它不能被关闭,但它应该有助于调试.
有没有办法从g ++中的demangled名称中找回受损的名称.
例如,我有demangled名称func(char*, int),我该怎么做才能获得受损的名称,即_Z4funcPci返回?
我的问题是g ++特定的.
我正在使用带有Win32的Stackdumps,将所有返回地址写入我的日志文件.我稍后会将这些与mapfile相匹配(参见我的文章[Post Mortem Debugging] [1]).
编辑::问题解决了 - 请参阅下面我自己的答案.
使用Windows x64,我找不到将返回地址写入日志文件的可靠方法.我试过几种方法:
试验1:指针算术:
CONTEXT Context;
RtlCaptureContext(&Context);
char *eNextBP = (char *)Context.Rdi;
for(ULONG Frame = 0; eNextBP ; Frame++)
{
char *pBP = eNextBP;
eNextBP = *(char **)pBP; // Next BP in Stack
fprintf(LogFile, "*** %2d called from %016LX (pBP at %016LX)\n", Frame,
(ULONG64)*(char **)(pBP + 8), (ULONG64)pBP);
}
Run Code Online (Sandbox Code Playgroud)
这在调试版本中运行良好 - 但它在发布版本中崩溃.Context.Rdi的值在那里没有可用的值.我确实检查了编译器设置的差异(visual Studio 2005).我没有发现任何可疑的东西.
试用版2:使用StackWalk64
RtlCaptureContext(&Context);
STACKFRAME64 stk;
memset(&stk, 0, sizeof(stk));
stk.AddrPC.Offset = Context.Rip;
stk.AddrPC.Mode = AddrModeFlat;
stk.AddrStack.Offset = Context.Rsp;
stk.AddrStack.Mode = AddrModeFlat;
stk.AddrFrame.Offset …Run Code Online (Sandbox Code Playgroud) void outputString(const char *str) {
cout << "outputString(const char *str) : " << str << endl;
}
Run Code Online (Sandbox Code Playgroud)
原来是
Dump of assembler code for function _Z12outputStringPKc:
0x004013ee <_Z12outputStringPKc+0>: push ebp
0x004013ef <_Z12outputStringPKc+1>: mov ebp,esp
0x004013f1 <_Z12outputStringPKc+3>: sub esp,0x8
0x004013f4 <_Z12outputStringPKc+6>: mov DWORD PTR [esp+4],0x443000
0x004013fc <_Z12outputStringPKc+14>: mov DWORD PTR [esp],0x4463c0
0x00401403 <_Z12outputStringPKc+21>: call 0x43f6e8 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc>
0x00401408 <_Z12outputStringPKc+26>: mov edx,DWORD PTR [ebp+8]
0x0040140b <_Z12outputStringPKc+29>: mov DWORD PTR [esp+4],edx
0x0040140f <_Z12outputStringPKc+33>: mov DWORD PTR [esp],eax
0x00401412 <_Z12outputStringPKc+36>: call 0x43f6e8 <_ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc>
0x00401417 <_Z12outputStringPKc+41>: mov …Run Code Online (Sandbox Code Playgroud) #include <iostream>
void do_something(void) {
std::cout << "blah blah" << std::endl;
auto lambda_func = [](void){
std::cout << "in lambda" << std::endl;
return;
};
lambda_func();
std::cout << "..." << std::endl;
return;
}
int main(int argc, char **argv) {
do_something();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在这个示例程序中,如果你编译(g++ gdb-call-lambda.cpp --std=c++11 -g)然后在gdb(gdb ./a.out)中运行它,你可以让GDB调用任何"普通"函数.例:
(gdb) break main
Breakpoint 1 at 0x4008e7: file gdb-call-lambda.cpp, line 20.
(gdb) r
Starting program: /home/keithb/dev/mytest/gdb-call-lambda/a.out
Breakpoint 1, main (argc=1, argv=0x7fffffffdfb8) at gdb-call-lambda.cpp:20
20 do_something();
(gdb) call do_something()
blah blah …Run Code Online (Sandbox Code Playgroud) 我想在Python程序中修改和解码C++函数名.有没有这样的东西?我现在搜索了几个小时,也许我很幸运...
我一直在尝试转储一组PE文件的所有导入的API函数调用。
我注意到大多数PE文件都有一组看起来很“奇怪”的导入功能。这些使我独特的函数调用数量大大增加,即使我觉得其中很多都是相同的函数调用。
经过进一步的研究,我发现这是由于名称处理所致,并且我目前正在寻找一种能够获取原始函数调用名称的解决方案(从某种意义上说,它更具可读性,也许可以减少我的数量)。唯一的函数调用)(如果可能),请使用Python而不是C ++。
我得到的一些例子:
?underflow@?$basic_streambuf@DU?$char_traits@D@std@@@std@@MAEHXZ
?setbuf@?$basic_streambuf@DU?$char_traits@D@std@@@std@@MAEPAV12@PAD_J@Z
??0exception@@QAE@ABQBD@Z
??0exception@@QAE@ABQBDH@Z
??0exception@@QAE@ABV0@@Z
??1exception@@UAE@XZ
Run Code Online (Sandbox Code Playgroud)
与
RegDeleteValueW
RegEnumKeyExW
RegCloseKey
RegQueryValueExW
RegSetValueExW
Run Code Online (Sandbox Code Playgroud) Hello社区我看看C++程序集,我已经从PARSEC套件编译了一个基准测试程序,我很难知道他们如何用汇编语言命名类属性函数.例如,如果我有一个类有一些函数来操作它,在cpp中我们称之为像test.increment();
经过一些调查我发现这个函数是
atomic_load_acq_ptr
Run Code Online (Sandbox Code Playgroud)
表示为:
_ZL19atomic_load_acq_intPVj
Run Code Online (Sandbox Code Playgroud)
在集会中,或者至少这是我发现的.
如果我错了,请告诉我!是否有一些固定的映射规则?或者他们是随机的?谢谢