我使用的是Delphi7和EurekaLog 7(在兼容模式下),只是想获得已处理异常的调用堆栈,比如
procedure CrossThreadFunc;
begin
try
SomeCode;
except
on E: Exception do
Log(CallStackOf(E));
end;
end;这是一个多线程的应用程序,所以如果可能的话,我想看看调用线程的调用堆栈。另外,由于这是一个已处理的异常,我还需要使用EurekaLog的OnExceptionRaise事件吗?(我不想这么做)。
编辑:使用一些参数多次调用CrossThreadFunc(),我需要知道的正是我调用它的位置,最终导致SomeCode()引发异常。
发布于 2019-06-11 19:14:29
有几种方法可以做到这一点,如EurekaLog's help中所述:
选项1
(仅限Delphi 2009+ )
假设您只需要一个文本表示:
except
on E: Exception do
Memo1.Lines.Text := E.StackTrace;
end;选项2
假设您可以访问RTL的exception对象:
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使用ECallStack;//
procedure TForm1.Button1Click(发送方: TObject);var CallStack: TEurekaBaseStackList;begin CallStack := GetCurrentCallStack;//您还可以使用ECallStack unit try Memo1.Lines.Text := CallStack.ToString中的其他函数;//您也可以使用CallStackToString(s)例程来自定义文本格式最终FreeAndNil(CallStack);end;end;
ThreadID属性来区分线程。
选项1
使用exception对象的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;可用的格式化程序包括:
附注:您可能还想考虑使用EurekaLog's logging procedures。
https://stackoverflow.com/questions/46881486
复制相似问题