在我看到CppCon 2015的这个演讲之后,我想对一些程序进行概述.我下载了那个人在谈话中使用的相同Google基准库,用适当的开关编译我的程序,将其链接到它,然后使用perf记录一次跑步.报告选项给了我这个:
正如您所看到的,函数名称不是很易读.我认为这与C++名称修改有关.有趣的是,所有的功能名称都在视频中正确显示给那个发表演讲的人,但不适合我.我不认为这是完全缺少符号信息的情况,因为在这种情况下我只会看到内存地址.由于某种原因,perf不能"撤消"我的C++名称,这看起来很令人沮丧.
我正在使用gcc(g ++)版本5.2.1,perf是版本4.2.6,我在编译时使用这些开关:
-I<my own include path> -L<path to the benchmark library> -O3 -std=c++14 -gdwarf-2 -fno-rtti -Wall -pedantic -lbenchmark -pthread
我不使用的原因-fno-omit-frame-pointer
是我使用了-gdwarf-2
选项,它将调试信息留在矮人可执行文件中,这是在这种情况下保留帧指针的替代方法.这也意味着我--call-graph "dwarf"
转到了perf record
.无论如何,我也尝试了帧指针方法,它给出了相同的结果,所以这并不重要.
那么为什么在这种情况下不会"撤消"C++名称错误?这与使用GCC有什么关系,这当然意味着我正在使用libstdc ++?
我以前,这里,已经表明,C++函数不容易在装配表示.现在我有兴趣阅读这种或那种方式,因为callgrind,valgrind的一部分,显示它们已经解组,而在汇编时它们被显示为损坏,所以我想要破坏valgrind函数输出或者取消函数的汇编名称.有没有尝试过类似的东西?我正在查看一个网站,发现以下内容:
Run Code Online (Sandbox Code Playgroud)Code to implement demangling is part of the GNU Binutils package; see libiberty/cplus-dem.c and include/demangle.h.
有人曾尝试过类似的东西,我想在C中进行demangle/mangle吗?我的编译器是gcc 4.x.
我想在Python程序中修改和解码C++函数名.有没有这样的东西?我现在搜索了几个小时,也许我很幸运...
我已经在SO上阅读了有关外部/内部联系的现有问题.我的问题是不同的-如果我的情况下有不同的翻译单元外部链接的同一个变量的多个定义会发生什么C
和C++
?
例如:
/*file1.c*/
typedef struct foo {
int a;
int b;
int c;
} foo;
foo xyz;
/*file2.c*/
typedef struct abc {
double x;
} foo;
foo xyz;
Run Code Online (Sandbox Code Playgroud)
使用Dev-C++和C程序,上述程序可以完美地编译和链接; 如果将其编译为C++程序,则会产生多重重定义错误.为什么它应该在C下工作?与C++有什么区别?此行为是否未定义且依赖于编译器?这段代码有多"糟糕",如果我想重构它,我该怎么办(我遇到过很多像这样编写的旧代码)?
我正在使用插件在Python中为IDA Pro反汇编程序编写脚本idapython
.使用此功能,我可以填补IDA自动分析不足的空白.
令我难以理解的一个领域是命名位置/功能(为了更好的术语)"漂亮的名字".我的意思的一个例子如下图所示:
idapython
和IDA Pro本身只允许我输入基本的C-ish函数名称.如果我输入不允许的符号(例如范围解析运算符),则将它们替换为下划线.但是,如果我手工输入一个受损的名字(例如__ZN9IOService15powerChangeDoneEm
),IDA Pro 会为我美化这个.
因此我的问题是:如何生成错位名称idapython
?有可用的名称库吗?有一个在Python中可用吗?我唯一的希望是将破坏功能从中解决g++
并解决这个问题吗?
在Raymond Chen的一篇文章中,他似乎能够从装饰名称中了解该函数的未修饰名称.我不知道他怎么能这样做.
在这个装饰的名字,
?的GetName @可通过按钮@ UILibrary @@ UAEPB_WPAPAVStringHolder @ 2 @@ž
每个组件的含义是什么?
Python标准库中是否有一个函数用于重现具有"私有"属性名称的Python名称修改方案?好像会有,但我找不到它的生命.
我写了这个,但如果有一个更好的方式,我会全神贯注.
def mangle_name (cls, attrname) :
prefix = '_' + cls.__name__.lstrip('_')
if not attrname.startswith('__') :
attrname = '__' + attrname
if not attrname.endswith('__') :
return prefix + attrname
else :
return attrname
class Foo :
__some_such = 3
name = mangle_name(Foo, '__some_such')
print name
print hasattr(Foo(), name)
Run Code Online (Sandbox Code Playgroud) 是否有可能在Delphi中取消这些名称?如果是这样,我在哪里可以获得更多信息?
它无法在dbrtl100.bpl中找到某个条目的错误消息示例我想知道它找不到哪个确切的函数(单位,类,名称,参数等).
---------------------------
myApp.exe - Entry Point Not Found
---------------------------
The procedure entry point @Dbcommon@GetTableNameFromSQLEx$qqrx17System@WideString25Dbcommon@IDENTIFIEROption could not be located in the dynamic link library dbrtl100.bpl.
---------------------------
OK
---------------------------
Run Code Online (Sandbox Code Playgroud)
我知道它是Dbcommon单元中的GetTableNameFromSQLEx方法(我有Delphi和RTL/VCL源代码),但有时我会遇到并非所有代码都可用的应用程序(是的,客户应该总是购买第三方的所有源代码)东西,但有时他们没有).
但是说这是一个我没有代码的例子,或只有接口文件(BDE.INT任何人?)它有什么参数(即哪个潜在的重载)?它有什么回报类型?
对于任何Delphi版本,这种破坏是否相同?
--jeroen
编辑1:
感谢Rob Kennedy:tdump -e dbrtl100.bpl可以解决问题.根本不需要-um:
C:\WINDOWS\system32>tdump -e dbrtl100.bpl | grep GetTableNameFromSQLEx
File STDIN:
00026050 1385 04AC __fastcall Dbcommon::GetTableNameFromSQLEx(const System::WideString, Dbcommon::IDENTIFIEROption)
Run Code Online (Sandbox Code Playgroud)
编辑2:
感谢TOndrej发现了这篇德语EDN文章(英文谷歌翻译).那篇文章非常准确地描述了格式,应该可以创建一些Delphi代码来解决这个问题.
Pitty,作者提到的网站(和电子邮件)现在已经死了,但很高兴知道这些信息.
--jeroen
我有一个需要C++ 11的项目,因此我将文件分为两类:使用C++ 11的文件和使用C++ 03的文件,因此与nvcc编译器兼容.当我有一个不是模板函数的内核时,很容易加载模块并使用找到函数名cuModuleGetDataEx
.但是,当内核是模板时,函数名称在显式特化后会被破坏.这使得在使用CUDA Driver API加载模块后很难获得函数的句柄.例如,考虑这个功能.
template <class T, class SizeType>
global void
vector_add(const T* a, const T* b, T* c, const SizeType dim)
{
const SizeType i = blockIdx.x * blockDim.x + threadIdx.x;
if (i < dim) { c[i] = a[i] + b[i]; }
}
在我将其编译成PTX代码之后,被破坏的名称是_Z10vector_addIfjEvPKT_S2_PS0_T0_
.如何从主机代码中轻松查找和加载模板内核函数,而无需在文件中手动查找并复制其名称?
我试图将32位dll(和应用程序)移植到64位,我已经设法构建它没有错误.当我尝试使用我的64位应用程序加载它时,我注意到导出的函数名称不同.这是我导出函数的方式:
#ifdef __cplusplus
extern "C" {
#endif
__declspec(dllexport) long __stdcall Connect(char * name, long size);
#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)
在Dependency Walker中,导出的函数具有以下格式:
32位: _Connect@8
64位: Connect
在使用dll的应用程序中,我显式加载了dll(LoadLibrary成功)但GetProcAddress因64位而失败,因为它找不到具有提供名称的函数.
在我们的应用程序中,我保留函数名称如下:
#define ConnectName "_Connect@8"
...
GetProcAddress(Dll, ConnectName);
Run Code Online (Sandbox Code Playgroud)
所以我想知道是否可以为32位和64位dll导出相同的函数名称,或者这是一个坏主意?或者我需要在我的应用程序中执行以下操作:
#if _WIN64
#define ConnectName "Connect"
#else
#define ConnectName "_Connect@8"
#endif
Run Code Online (Sandbox Code Playgroud)
我感谢任何帮助.