[讨论] 为什么有时候调试代码的时候看不到变量的值。
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吧?
|
相关讨论
相关资源推荐
- 误操作导致debug状态下没有变量值,debug状态下代码后面不显示变量值
- clion在调试时在代码处自动显示变量值
- keil debug如何在watch直接修改变量值_KEIL 调试经验总结
- eclipse打断点调试进入到class文件中,不显示变量值的解决办法汇总
- Visual Studio在Release模式下开启debug调试,编译器提示变量已被优化掉,因而不可用
- Delphi在调试的时候查看变量的值
- Pycharm debug时变量值显示不出或显示不完全
- eclipse在debug模式下鼠标移动到变量上不显示值的问题
- 为什么要学习C++软件调试技术?掌握调试技术都有哪些好处?
- VS2019调试查看变量_你很可能需要知道这个调试小技巧