【调试中非常重要的技巧】如何从错误堆栈的输出判断程序出错的准确位置?

原创 2017年01月03日 01:15:24
大家都知道在非J2ME程序中,捕捉异常后用ex.printStackTrace()可以得到错误堆栈,错误堆栈中除了有错误信息(原因)外,还有抛出异常的位置在源文件的行数,从而可以准确地定位错误。
  但是在J2ME程序中,用ex.printStackTrace()输出的信息似乎并不是抛出异常的位置在源文件的准确行数,现在有一个简单示例如下:
  类MIDletTest2.java:
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import java.io.*;

public class MIDletTest2 extends MIDlet
{
  MyCanvas myCan;

  public MIDletTest2()
  {
    myCan = new MyCanvas();
  }
  protected void pauseApp()
  {

  }
  protected void startApp()
  {
    Display.getDisplay(this).setCurrent(myCan);
  }
  protected void destroyApp(boolean parm1)
  {

  }
}

  类MyCanvas.java:
import javax.microedition.lcdui.*;

public class MyCanvas extends Canvas
{
  Image img;

  public MyCanvas()
  {

  }

  protected void paint(Graphics g)
  {
    try
    {
      img = Image.createImage("/err/err.png");//抛出异常的地方
    }
    catch (Exception ex)
    {
      ex.printStackTrace();
    }
    g.drawImage(img, 0, 0, g.TOP|g.LEFT);
  }
}
  err.png是不存在的文件,很明显当首次调用paint时,会因为找不到图片文件而抛出异常,下面看抛出异常的错误堆栈信息:
  java.io.IOException: Couldn't find resource
at javax.microedition.lcdui.Image.<init>(+36)
at javax.microedition.lcdui.Image.createImage(+8)
at MyCanvas.paint(+6)
at javax.microedition.lcdui.Canvas.paint(+149)
at javax.microedition.lcdui.Canvas.serviceRepaints(+8)
at javax.microedition.lcdui.Canvas.handleShown(+42)
at javax.microedition.lcdui.Canvas.handleCurrent(+26)
at javax.microedition.lcdui.Display.setCurrent(+81)
at MIDletTest2.startApp(+11)
at javax.microedition.midlet.MIDletInvoker.invokeStartApp(+4)
at com.symbian.midp.compatibility.runtime.MIDletScheduler.startMIDlet(+29)
at com.symbian.midp.compatibility.runtime.MultiMIDletScheduler.run(+17)
    接下来就看不懂了,首先每行的括号里面的+号是什么意思,此外+号后面的数字并不是抛出异常的位置在源文件中的准确行数。请大家给予解答。


VS堆栈调试技巧

位置: 调试 >> 窗口 >> 调用堆栈 说明: 任何一个项目都会对项目进行各种层次和模块的划分,不管新手老手,在调试代码的时候(尤其是维护项目,修改别人的代码)还是经常会因为不知道代码是如何传递...
  • jiangnanyidiao
  • jiangnanyidiao
  • 2014年07月17日 11:21
  • 2776

ios中对堆栈的理解及两者件的区别

Objective-C的对象在内存中是以堆的方式分配空间的,并且堆内存是由你释放的,即release 栈由编译器管理自动释放的,在方法中(函数体)定义的变量通常是在栈内,因此如果你的变量要跨函数的话...
  • Tina__March
  • Tina__March
  • 2015年10月17日 16:05
  • 1822

matlab调试技巧

Matlab的调试总体分为,直接调试和间接调试。 1.直接调试: (1)去掉句末的分号; (2)单独调试一个函数:将第一行的函数声明注释掉,并定义输入量,以脚本方式执行 M 文件; (3)适当...
  • neal1991
  • neal1991
  • 2015年10月13日 18:49
  • 1188

如何:查看堆栈跟踪并定位到失败点

 在运行单元测试并接收到失败结果之后,可以查看堆栈跟踪来了解有关测试失败的上下文信息。也可以直接定位到测试中的失败点。说明:堆栈跟踪只对单元测试可用。 堆栈跟踪显示在 Visual Studio 中的...
  • yaoxy
  • yaoxy
  • 2009年04月14日 15:48
  • 2099

关于VS中的错误处理和调试

关于错误和调试的基本概念 错误 语法错误:比如变量名错误等,导致编译器无法编译,编译器能够实时报错 //语法错误,变量名出错 int temp = 235; ...
  • qq_37365407
  • qq_37365407
  • 2017年09月22日 11:33
  • 142

判断栈输出顺序正确与否(西电OJ题目)

问题描述 给定一个栈,其中最多存储M个数据。将N个数据以1,2,3,...,N的顺序压栈,然后再随机弹栈。判断一下哪些是有可能的弹栈顺序,而哪些不是。例如M是5,N是7,我们可以得到1, 2, 3,...
  • u013632190
  • u013632190
  • 2015年06月02日 10:33
  • 1343

QT 的基础调试技巧 -- 未完 -- 更新中

1 QT creator 里面 1.1 加打印的方法 qDebug()"---hsy--test--showtable---"; 这条加了之后,程序走到这里,就会在应用程序输出那里打印出...
  • yellow_hill
  • yellow_hill
  • 2017年06月22日 11:48
  • 268

《剑指offer》:[22]如何判断一个序列是否为栈的弹出序列

题目:输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。 假设压入栈的所有数字均不相等。例如序列1,2,3,4,5是某栈的压栈序列,序列4,5,3,2,1是该压栈序列...
  • gogoky
  • gogoky
  • 2016年06月07日 09:51
  • 785

VS的vcxproj文件 + 调试技巧之调用堆栈 + 每次重新编译

[摘要]    详细了解vcxproj.filters文件后,你可以在你的解决方案管理器中按照你自己的分类习惯对文件进行分类。每种类别都以文件夹的形式存放,当然只是在解决方案管理器中显示而已。虽然可以...
  • u013321328
  • u013321328
  • 2016年03月22日 14:54
  • 1195

基于嵌入式操作系统的实时性多任务划分方法

UCOSII_ARM  多任务划分方法与原则        谈几点多任务的划分原则:任务划分是必须清楚的认识到任务的性质和特点然后根据具体的特点对人物的优先级、堆栈等运行属性进行划分。 1、设备依...
  • grand_duke
  • grand_duke
  • 2016年04月15日 15:23
  • 1061
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:【调试中非常重要的技巧】如何从错误堆栈的输出判断程序出错的准确位置?
举报原因:
原因补充:

(最多只允许输入30个字)