[讨论] 为什么有时候调试代码的时候看不到变量的值。

RednaxelaFX 2011-04-26
xgj1988 写道
2:就是RednaxelaFX给的最后的东西不太明白是什么。哈哈

引用
j2se/make/common/Defs.gmk
Makefile代码 
# Any debug build should include all debug info inside the classfiles  
ifeq ($(VARIANT), DBG)  
  DEBUG_CLASSFILES = true  
endif  
ifeq ($(DEBUG_CLASSFILES),true)  
  JAVACFLAGS_COMMON += -g  
endif  
 
JAVACFLAGS     = $(JAVACFLAGS_COMMON) $(OTHER_JAVACFLAGS)  
JAVAC_CMD      = $(JAVAC) $(JIT_OPTION) $(JAVACFLAGS) $(LANGUAGE_VERSION) $(CLASS_VERSION)
在debug build里才有-g。

这个是JDK的build脚本里的一小段代码,用来设定Java源码的编译参数的。rt.jar里的内容就是用这参数编译出来的。可以看到,只有debug build里Java源码编译的时候才会用上了-g参数。

xgj1988 写道
2:我把add variable attributes to generated class file 关闭之后,可以调试源代码,但是出现a can't be resolved ,注意,这里可能是我在最开始就没表述清楚,我这里说的不can't be resolved是我在eclipse里面用watch和inspect试图的时候就会can't be resolved ,但是在variables里面会显示出他的值,但是这样又有一个新问题。也就是a,b,c变量名变成了arg0,arg1,arg2这样的形式。所以可能IcyFenix也没太懂我的意思。

这是因为调试器可以知道方法的签名是什么,从而得知有多少个、什么类型的参数。但缺少LocalVariableTable就无法知道具体的参数名,所以就显示成arg0、arg1这样了。

你可以试试,在不输出LocalVariableTable的前提下,看看真正的局部变量(而不是参数)的值能不能在Eclipse的调试器的variable窗口里看到?
xgj1988 2011-04-26
为什么variable下面可以看到a,b,c的信息,但是在watch和inspect就不行了?

哦。。这样哦。但是第一个问题还是没搞清楚。


RednaxelaFX 2011-04-26
xgj1988 写道
为什么variable下面可以看到a,b,c的信息,但是在watch和inspect就不行了?

哦。。这样哦。但是第一个问题还是没搞清楚。

呃我以为那个不用解释…
调试器依赖LineNumberTable属性来得知源码中的行号与字节码的偏移量之间的对应关系。没有它就无法在具体的行设断点。

javac默认会生成LineNumberTable,传-g:lines跟完全不传-g相关参数是一样的。如果使用-g:none来剥离所有调试符号信息那就没有LineNumberTable属性表,也就没法调试了
xgj1988 2011-04-26
RednaxelaFX 写道
xgj1988 写道
为什么variable下面可以看到a,b,c的信息,但是在watch和inspect就不行了?

哦。。这样哦。但是第一个问题还是没搞清楚。

呃我以为那个不用解释…
调试器依赖LineNumberTable属性来得知源码中的行号与字节码的偏移量之间的对应关系。没有它就无法在具体的行设断点。

javac默认会生成LineNumberTable,传-g:lines跟完全不传-g相关参数是一样的。如果使用-g:none来剥离所有调试符号信息那就没有LineNumberTable属性表,也就没法调试了



呵呵,刚才可能思路有点混乱,现在想通了。。了解了。不知道
http://hllvm.group.iteye.com/group/topic/25810

这个是什么回事。帮看看。
sswh 2011-04-27
xgj1988 写道
所以问题就是:
1:为什么variable下面可以看到a,b,c的信息,但是在watch和inspect就不行了?


还是没有局部变量表的原因。

你在variable下面可以看到方法参数写成arg0,arg1的形式,但是方法体内的局部变量在variable下面是没有的,你没有发现吗?

(正常情况下variable下面包括this、方法参数、方法局部变量3部分,如果没有局部变量表的话,方法局部变量就不见了)

按照这一点来猜测的话,watch和inspect是根据选择的变量名称,先去找局部变量表,获取该变量在局部变量表内的偏移,然后找到具体值的。

而variable下面是固定按照0、1、2顺序来显示变量值的,当然可以看到了。

以前也在javaeye上问过这个问题,那时候没人搭理,对比了一下楼主的提问方式,也许是我没有截图,问题没有描述清楚的原因吧-_-

http://www.iteye.com/topic/150851#436700

sswh 2011-04-27
晕  没有看到第2页的内容  呵呵。
xgj1988 2011-04-27
sswh 写道
晕  没有看到第2页的内容  呵呵。


但是,还是谢谢你的回答。。
xgj1988 2011-04-27
RednaxelaFX 写道
xgj1988 写道
2:就是RednaxelaFX给的最后的东西不太明白是什么。哈哈

引用
j2se/make/common/Defs.gmk
Makefile代码 
# Any debug build should include all debug info inside the classfiles  
ifeq ($(VARIANT), DBG)  
  DEBUG_CLASSFILES = true  
endif  
ifeq ($(DEBUG_CLASSFILES),true)  
  JAVACFLAGS_COMMON += -g  
endif  
 
JAVACFLAGS     = $(JAVACFLAGS_COMMON) $(OTHER_JAVACFLAGS)  
JAVAC_CMD      = $(JAVAC) $(JIT_OPTION) $(JAVACFLAGS) $(LANGUAGE_VERSION) $(CLASS_VERSION)
在debug build里才有-g。

这个是JDK的build脚本里的一小段代码,用来设定Java源码的编译参数的。rt.jar里的内容就是用这参数编译出来的。可以看到,只有debug build里Java源码编译的时候才会用上了-g参数。

xgj1988 写道
2:我把add variable attributes to generated class file 关闭之后,可以调试源代码,但是出现a can't be resolved ,注意,这里可能是我在最开始就没表述清楚,我这里说的不can't be resolved是我在eclipse里面用watch和inspect试图的时候就会can't be resolved ,但是在variables里面会显示出他的值,但是这样又有一个新问题。也就是a,b,c变量名变成了arg0,arg1,arg2这样的形式。所以可能IcyFenix也没太懂我的意思。

这是因为调试器可以知道方法的签名是什么,从而得知有多少个、什么类型的参数。但缺少LocalVariableTable就无法知道具体的参数名,所以就显示成arg0、arg1这样了。

你可以试试,在不输出LocalVariableTable的前提下,看看真正的局部变量(而不是参数)的值能不能在Eclipse的调试器的variable窗口里看到?




不知道sun是否有一个带有localvariabletable  的 jar包。 这样调试的时候就很方便了。
IcyFenix 2011-04-27
自己编一个呀,编一份debug版的(SKIP_DEBUG_BUILD=false)。
ordinary 2011-04-27
我来问一句,有时用泛型看不到变量的名也是因为编译没用 -g吧?
Global site tag (gtag.js) - Google Analytics