在Delphi中可以在运行时获取源行号吗?我知道JCL调试,但我想避免使用它.Assert也不是我想要的.我想得到这样的东西,GetLineNumber将得到源代码行.是否可以在没有MAP文件的情况下执行此操作(无论如何,当我使用Assert时会生成MAP文件)?有什么例子吗?
function GetLineNumber: integer;
begin
???
end;
procedure ThisWouldBeGreat;
begin
if not SomeCondition then
LogMemo.Lines.Add('Error on line: ' + IntToStr(GetLineNumber));
end;
procedure ThatsWhatIWont;
begin
Assert(not SomeCondition, 'Error');
end;
Run Code Online (Sandbox Code Playgroud)
谢谢
Rob*_*edy 11
你确实可以用Assert它.编写一个与TAssertErrorProc类型所指示的签名相匹配的过程,然后在那里做任何你想做的事情.为了保留预期的行为,您应该在完成后调用原始处理程序.
procedure MichaelAssertProc(const Message, Filename: string;
LineNumber: Integer; ErrorAddr: Pointer);
begin
LogMessage(...);
SysUtils.AssertErrorHandler(Message, Filename, LineNumber, ErrorAddr);
end;
Run Code Online (Sandbox Code Playgroud)
System.AssertErrorProc在程序启动时将该过程分配给某个时间.
AssertErrorProc := MichaelAssertProc;
Run Code Online (Sandbox Code Playgroud)
对于我们的日志记录和异常跟踪类,我们创建了一个.map解析器和读取器.
.map可以解析为二进制压缩版本(.mab专有格式),比原始.map小得多.例如,一个900 KB的.map文件被压缩成一个70 KB的.mab文件 - 这比zip压缩得多.
此.mab内容可以附加到.exe,执行时没有任何差异,或者最终用户.
然后你可以使用我们的日志类,或者直接使用.map/.mab阅读器类TSynMapFile.
您手头有以下方法:
/// retrieve a .map file content, to be used e.g. with TSynLog to provide
// additional debugging information
// - original .map content can be saved as .mab file in a more optimized format
TSynMapFile = class
public
/// get the available debugging information
// - will first search for a .map file in the .exe directory: if found,
// will be read to retrieve all necessary debugging information - a .mab
// file will be also created in the same directory (if MabCreate is TRUE)
// - if .map is not not available, will search for the .mab file in the
// .exe directory
// - if no .mab is available, will search for a .mab appended to the exe
// - if nothing is available, will log as hexadecimal pointers, without
// debugging information
// - if aExeName is not specified, will use the current process executable
constructor Create(const aExeName: TFileName=''; MabCreate: boolean=true);
/// save all debugging information in the .mab custom binary format
// - if no file name is specified, it will be saved as ExeName.mab
// - this file content can be appended to the executable via SaveToExe method
// - this function returns the created file name
function SaveToFile(const aFileName: TFileName=''): TFileName;
/// save all debugging informat in our custom binary format
procedure SaveToStream(aStream: TStream);
/// append all debugging information to an executable
// - the executable name must be specified, because it's impossible to
// write to the executable of a running process
procedure SaveToExe(const aExeName: TFileName);
/// add some debugging information according to the specified memory address
// - will create a global TSynMapFile instance for the current process, if
// necessary
// - if no debugging information is available (.map or .mab), will write
// the address as hexadecimal
class procedure Log(W: TTextWriter; Addr: PtrUInt);
/// retrieve a symbol according to an absolute code address
function FindSymbol(aAddr: cardinal): integer;
/// retrieve an unit and source line, according to an absolute code address
function FindUnit(aAddr: cardinal; out LineNumber: integer): integer;
/// return the symbol location according to the supplied absolute address
// - i.e. unit name, symbol name and line number (if any), as plain text
// - returns '' if no match found
function FindLocation(aAddr: Cardinal): RawUTF8;
/// all symbols associated to the executable
property Symbols: TSynMapSymbolDynArray read fSymbol;
/// all units, including line numbers, associated to the executable
property Units: TSynMapUnitDynArray read fUnit;
published
/// the associated file name
property FileName: TFileName read fMapFile;
/// equals true if a .map or .mab debugging information has been loaded
property HasDebugInfo: boolean read fHasDebugInfo;
end;
Run Code Online (Sandbox Code Playgroud)
感谢这个课程,只需一个单元,您就可以拥有任何位置的所有源代码行.
开源,并使用Delphi 5到XE(请注意.map格式从旧版本到新版本稍有变化 - 我们的类尝试处理它).
| 归档时间: |
|
| 查看次数: |
11776 次 |
| 最近记录: |