【问题标题】:gprolog: Getting a stacktrace after an exceptiongprolog:异常后获取堆栈跟踪
【发布时间】:2023-03-22 08:10:01
【问题描述】:

在使用 gprolog 时,我经常遇到没有任何类型的行号或上下文的异常:

uncaught exception: error(instantiation_error,(is)/2)

没有任何上下文。我知道我可以做一个trace,但是用trace 调试它需要很长时间,因为在到达错误发生的地方之前我需要执行很多事情。

关于如何拥有这个堆栈跟踪的任何想法?还是动态的trace/notrace

编辑:或者只是自动打印整个 trace 输出。

【问题讨论】:

    标签: debugging prolog gnu-prolog


    【解决方案1】:

    @gusbro 的回答 (s(X)) 向您展示了如何使用 GNU 的调试器解决这个问题。但是,如果您无法看到所有的打印正在进行,或者打印速度太慢,您可以考虑在 Scryer 中以library(debug) 的形式提供以下“调试器”。

    我个人不使用 Prolog 系统提供的调试器,原因很简单,因为它们中的大多数打印太多,本身经常出错,并且有自己特定的不断变化的约定,我学不起。

    :- op(900, fx, [@,$,$-]).
    
    $-(G_0) :-
       catch(G_0, Ex, ( portray_clause(exception:Ex:G_0), throw(Ex) ) ).
    
    $(G_0) :-
       portray_clause(call:G_0),
       $-G_0,
       portray_clause(exit:G_0).
    
    @(G_0) :-
       (   $-G_0
       *-> true
       ;   portray_clause(badfail:G_0),
           throw(goal_failed(G_0))
       ).
    
    :- op(950, fy, *).
    *(_).
    

    要使用它,只需在特定目标前添加$-$@

    $- 表示:仅表示通过此目标的异常

    $另外显示调用和退出

    @ 保证至少有一个答案,如果没有,则报告并抛出异常。

    谨慎使用上述注释!

    * 删除目标。这是为了在纯单调程序中泛化一个程序修改/。在意外失败的情况下您需要这个。有关如何使用它的示例,请参阅以下答案/调试会话 1, 2, 3, 4, 5, 6, 7, 8, 9, 10.

    _/*term*/ 用匿名变量替换术语。这比单独的* 更能概括程序。示例会话: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10.

    通过这种方式,您可以显着减少您观看的信息。

    在其他支持meta_predicate 指令的系统中,如 SICStus、YAP 和 SWI,在前面添加以下指令:

    :- meta_predicate(( $-(0), $(0), @(0) )).
    

    【讨论】:

    • 哇,这两种解决方案都很棒!非常感谢!
    【解决方案2】:

    你可以trace/0leash/1只有exception端口,例如:

    ?- trace.
    ?- leash([exception]).
    

    然后你运行你的程序,它会在屏幕上打印一个跟踪,但只有在发生异常时才会停止。在那里,您可以通过按字母g 来查看“堆栈跟踪”(祖先)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-05
      • 2011-06-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-06
      • 2010-09-13
      相关资源
      最近更新 更多