代码之家  ›  专栏  ›  技术社区  ›  Andrew Janke

Matlab错误中的双倍行距Java堆栈跟踪

  •  2
  • Andrew Janke  · 技术社区  · 15 年前

    package test;
    
    public class Bummer {
       public static void a() { b(); }
       public static void b() { c(); }
       public static void c() { d(); }
       public static void d() { throw new RuntimeException("bummer"); }
    }
    

    这就产生了这个。

    >> test.Bummer.a()
    ??? Java exception occurred:
    java.lang.RuntimeException: bummer
    
        at test.Bummer.d(Bummer.java:8)
    
        at test.Bummer.c(Bummer.java:7)
    
        at test.Bummer.b(Bummer.java:6)
    
        at test.Bummer.a(Bummer.java:5)
    
    
    >> disp(find(lasterr == sprintf('\r')))
        61    95   129   163   197
    

    这会损害可读性,尤其是当您有一个20调用深度堆栈时。

    我认为这是因为错误消息的stacktrace部分是用DOS模式CRLF(\r\n)行结尾构造的。这在Windows机器上是有意义的。但Matlab命令窗口是一种Unix模式,它将\r\n转换为两个换行符。

    我们目前的解决方法是在大多数Java方法调用中使用类似这样的try/catch保护代码。

    try
       somejavaobject.SomeMethod();
    catch err
       rethrowmsg(err, 'Some additional details');
    end
    

    Rethrowmsg()是我们编写的一个函数,它将\r\n munges err转换为\r\n,在消息中包含其他详细信息,然后调用RETHROW。

    添加变通方法有点乏味,而且容易被忽略。如果您正在执行“dbstop if all error”,它不会修复错误在该点的显示。最后,这是一个小麻烦,但当你花了一整天的时间调试Matlab代码时,它就加起来了。我对Java异常/meexception集成机制很好奇。

    3 回复  |  直到 15 年前
        1
  •  1
  •   Mike Katz    15 年前

    当MATLAB运行时截获java异常时,当它将它包装在meexception中时,它使用系统行结尾。为了避免这种情况,您可以在另一个线程上抛出异常,或者直接将堆栈跟踪发送到stderr,例如使用printStackTrace():

    public class Bummer {
     public static void a() { b(); }
     public static void b() { c(); }
     public static void c() { d(); }
     public static void d() { new RuntimeException("bummer").printStackTrace(); }
    }
    

    如果您使用异常来调试java代码,我发现大多数javaide的堆栈跟踪分析函数都能够很好地处理额外的换行符。

        2
  •  1
  •   andrewsi Laxman Battini    12 年前

    尝试设置:

    java.lang.System.setProperty('line.separator', sprintf('\n'));
    
        3
  •  0
  •   gnovice    15 年前

    使用 FORMAT 完全改善了命令的显示吗?这有助于以更紧凑的形式显示变量:

    format compact