Map := TSynMapFile.Create; // or specify an exe name
try
i := Map.FindSymbol(SymbolAddr);
if i>=0 then
writeln(Map.Symbols[i].Name);
// or for your point:
writeln(Map.FindLocation(Addr)); // e.g. 'SynSelfTests.TestPeopleProc (784)'
finally
Map.Free;
end;
例如,下面是如何从我们的日志记录类中使用它。
procedure TSynLog.Log(Level: TSynLogInfo);
var aCaller: PtrUInt;
begin
if (self<>nil) and (Level in fFamily.fLevel) then begin
LogHeaderLock(Level);
asm
mov eax,[ebp+4] // retrieve caller EIP from push ebp; mov ebp,esp
sub eax,5 // ignore call TSynLog.Enter op codes
mov aCaller,eax
end;
TSynMapFile.Log(fWriter,aCaller); // here it will call TSynMapFile for the current exe
LogTrailerUnLock(Level);
end;
end;
3条答案
按热度按时间qyuhtwio1#
JCL是自由的,并且有相关的函数。这取决于堆栈跟踪的效果如何,以及存在多少调试信息。
JclDebug.pas
smdncfj32#
另请参见our
TSynMapFile
class。它能够加载
.map
文件,并将其压缩为优化的二进制格式。它将比.map
本身小得多(例如900 KB.map
-〉70 KB.mab
)。此.mab
可以轻松嵌入到exe中。因此,它比JCL或MadExcept使用的格式小,并且也小于由Delphi在编译时嵌入的信息。您将按如下方式使用它:
例如,下面是如何从我们的日志记录类中使用它。
此方法能够检索调用者的地址,并记录其单元名、方法名和行号。
注/编辑:mORMot日志单元的源代码为SynLog.pas,更新后的文档可以在这个URI上找到。
yruzcnhs3#
如果您有EurekaLog:
还有
__FILE__
、__MODULE__
、__UNIT__
、__LINE__
,以及一个通用的GetLocationInfoStr
函数。然而:
1.只有在使用一些调试信息(以及corresponding debug info provider is enabled)进行编译时,它才能工作:
1.它不是一个常量。名字将被动态查找,所以它有一些运行时间开销。