首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用EurekaLog获取已处理异常的调用堆栈

如何使用EurekaLog获取已处理异常的调用堆栈
EN

Stack Overflow用户
提问于 2017-10-23 11:20:16
回答 1查看 244关注 0票数 1

我使用的是Delphi7和EurekaLog 7(在兼容模式下),只是想获得已处理异常的调用堆栈,比如

代码语言:javascript
复制
procedure CrossThreadFunc;
begin
  try
    SomeCode;
  except
    on E: Exception do
      Log(CallStackOf(E));
  end;
end;

这是一个多线程的应用程序,所以如果可能的话,我想看看调用线程的调用堆栈。另外,由于这是一个已处理的异常,我还需要使用EurekaLog的OnExceptionRaise事件吗?(我不想这么做)。

编辑:使用一些参数多次调用CrossThreadFunc(),我需要知道的正是我调用它的位置,最终导致SomeCode()引发异常。

EN

回答 1

Stack Overflow用户

发布于 2019-06-11 19:14:29

有几种方法可以做到这一点,如EurekaLog's help中所述:

选项1

(仅限Delphi 2009+ )

假设您只需要一个文本表示:

代码语言:javascript
复制
except
  on E: Exception do
    Memo1.Lines.Text := E.StackTrace;
end;

选项2

假设您可以访问RTL的exception对象:

代码语言:javascript
复制
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中的错误,您可能需要这样写:

代码语言:javascript
复制
EI := ExceptionManager.Info(Pointer(E));

选项3

假设您可以访问EurekaLog的异常信息对象(例如事件处理程序中的参数):

代码语言:javascript
复制
uses
  EException, // for TEurekaExceptionInfo 
  ECallStack; // for TEurekaBaseStackList

{ ... } AExceptionInfo: TEurekaExceptionInfo; { ... }
var
  CallStack: TEurekaBaseStackList;
begin
  CallStack := AExceptionInfo.CallStack;
end;

选项4

假设你想为当前线程中的最后一个(例如最近的)异常调用堆栈:

代码语言:javascript
复制
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属性来区分线程。

  • 如果需要将检索到的调用堆栈转换为文本/字符串表示形式以进行日志记录,请参见this

选项1

使用exception对象的StackTrace属性(Delphi 2009+):

代码语言:javascript
复制
except
  on E: Exception do
    Memo1.Lines.Text := E.StackTrace;
end;

选项2

使用ToString方法将调用堆栈转换为具有默认格式的单个字符串:

代码语言:javascript
复制
var
  CallStack: TEurekaBaseStackList;
begin
  CallStack := { ... somehow retrieve call stack ... };
  Memo1.Lines.Text := CallStack.ToString;
end;

选项3

使用Assign方法将调用堆栈转换为默认格式的TStrings对象:

代码语言:javascript
复制
var
  CallStack: TEurekaBaseStackList;
begin
  CallStack := { ... somehow retrieve call stack ... };
  Memo1.Lines.Assign(CallStack);
end;

选项4

ECallStack单元使用CallStackToString函数:

代码语言:javascript
复制
// (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函数:

代码语言:javascript
复制
// (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样式调用堆栈(即有列的固定宽度表格)的通用格式化程序-最好用于文本files
  • TEurekaStackFormatterV6 -向后兼容格式化程序,以生成EurekaLog V6格式的调用堆栈(较少的列-生成适合于可变宽度字体的调用堆栈的列表视图(无列))(最好用于消息boxes)
  • TCompactStackFormatter -类似于TSimpleStackFormatter,但生成的输出更紧凑,细节更少(适合快速预览)

附注:您可能还想考虑使用EurekaLog's logging procedures

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46881486

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档