有几种方法可以做到这一点,在EurekaLog's help中描述:
选项 1
(仅限 Delphi 2009+)
假设您只需要文本表示:
except
on E: Exception do
Memo1.Lines.Text := E.StackTrace;
end;
选项 2
假设您可以访问 RTL 的异常对象:
uses
EExceptionManager, // for ExceptionManager
EException, // for TEurekaExceptionInfo
ECallStack; // for TEurekaBaseStackList
var
EI: TEurekaExceptionInfo;
CallStack: TEurekaBaseStackList;
// ...
except
on E: Exception do
begin
EI := ExceptionManager.Info(E);
// EI would be nil, if EurekaLog is disabled
// or event handlers instruct EurekaLog to skip this exception
if Assigned(EI) then
CallStack := EI.CallStack;
end;
end;
注意:由于某些旧 IDE 中存在错误,您可能需要这样编写:
EI := ExceptionManager.Info(Pointer(E));
选项 3
假设您可以访问 EurekaLog 的异常信息对象(例如事件处理程序中的参数):
uses
EException, // for TEurekaExceptionInfo
ECallStack; // for TEurekaBaseStackList
{ ... } AExceptionInfo: TEurekaExceptionInfo; { ... }
var
CallStack: TEurekaBaseStackList;
begin
CallStack := AExceptionInfo.CallStack;
end;
选项 4
假设您希望当前线程中最后一个(例如最近的)异常的调用堆栈:
uses
EExceptionManager, // for ExceptionManager
EException, // for TEurekaExceptionInfo
ECallStack; // for TEurekaBaseStackList
var
EI: TEurekaExceptionInfo;
CallStack: TEurekaBaseStackList;
begin
EI := ExceptionManager.LastThreadException;
// EI would be nil, if EurekaLog is disabled
// or event handlers instruct EurekaLog to skip this exception
if Assigned(EI) then
CallStack := EI.CallStack;
end;
注意事项:
-
如果您需要当前调用堆栈 - 使用来自 ECallStack 单元的 GetCurrentCallStack 函数:
用途
调用堆栈; // 用于 TEurekaBaseStackList 和 GetCurrentCallStack
过程 TForm1.Button1Click(Sender: TObject);
变量
调用堆栈:TEurekaBaseStackList;
开始
CallStack := GetCurrentCallStack;
// 你也可以使用 ECallStack 单元中的其他函数
尝试
Memo1.Lines.Text := CallStack.ToString;
// 您还可以使用 CallStackToString(s) 例程来自定义文本格式
最后
FreeAndNil(CallStack);
结尾;
结束;
如果您需要来自其他线程的调用堆栈 - 只需在选项中进行设置,所有启用的线程的调用堆栈都将包含在同一个调用堆栈对象中。您可以通过调用堆栈条目的ThreadID 属性来区分线程。
如果您需要将检索到的调用堆栈转换为文本/字符串表示以进行记录,请参阅this:
选项 1
使用异常对象的StackTrace 属性(Delphi 2009+):
except
on E: Exception do
Memo1.Lines.Text := E.StackTrace;
end;
选项 2
使用ToString 方法将调用堆栈转换为具有默认格式的单个字符串:
var
CallStack: TEurekaBaseStackList;
begin
CallStack := { ... somehow retrieve call stack ... };
Memo1.Lines.Text := CallStack.ToString;
end;
选项 3
使用Assign 方法将调用堆栈转换为TStrings 具有默认格式的对象:
var
CallStack: TEurekaBaseStackList;
begin
CallStack := { ... somehow retrieve call stack ... };
Memo1.Lines.Assign(CallStack);
end;
选项 4
使用ECallStack单元中的CallStackToString函数:
// (CallStackToString function allows you to override header and formatting)
var
CallStack: TEurekaBaseStackList;
Formatter: TCompactStackFormatter;
begin
CallStack := { ... somehow retrieve call stack ... };
// A): Default formatting and header:
Memo1.Lines.Text := CallStackToString(CallStack);
// B): With custom header:
Memo1.Lines.Text := CallStackToString(CallStack, 'Error Details:');
// C): Custom formatting:
Formatter := TCompactStackFormatter.Create;
try
// <- here you can customize Formatter (for example: alter captions for columns, etc.)
Memo1.Lines.Text := CallStackToString(CallStack, '', Formatter);
finally
FreeAndNil(Formatter);
end;
end;
选项 5
使用ECallStack单元中的CallStackToStrings函数:
// (CallStackToStrings function allows you to override header and formatting)
var
CallStack: TEurekaBaseStackList;
Formatter: TCompactStackFormatter;
begin
CallStack := { ... somehow retrieve call stack ... };
// A): Default formatting and header:
CallStackToStrings(CallStack, Memo1.Lines);
// B): With custom header:
CallStackToStrings(CallStack, Memo1.Lines, 'Error Details:');
// C): Custom formatting:
Formatter := TCompactStackFormatter.Create;
try
// <- here you can customize Formatter (for example: alter captions for columns, etc.)
CallStackToStrings(CallStack, Memo1.Lines, '', Formatter);
finally
FreeAndNil(Formatter);
end;
end;
可用的格式化程序有:
- TEurekaStackFormatter - EurekaLog 样式调用堆栈的通用格式化程序(即带列的固定宽度表) - 最适合在文本文件中使用
- TEurekaStackFormatterV6 - 向后兼容的格式化程序,以 EurekaLog V6 格式生成调用堆栈(更少的列)
- TSimpleStackFormatter - 生成类似列表的调用堆栈视图(无列),适用于可变宽度字体(最好在消息框中使用)
- TCompactStackFormatter - 类似于 TSimpleStackFormatter,但输出更紧凑,细节更少(适合快速预览)
附:您可能还想考虑EurekaLog's logging procedures。