简体   繁体   中英

When does the JVM omit line info in a stack trace and how can I prevent it?

I have a very confusing situation:

I have a class that is compiled with line info on (verified using javap -l ). This class gets loaded and instrumented with ASM. I verified that the correct class is loaded (ie not a stale class file from somewhere else). And I also made sure that the ASM flag ClassReader.SKIP_DEBUG is not set. Now if I call Thread.currentThread().getStackTrace() , I get StackTraceElement s concerning this class that miss the line info. When debugging in Eclipse, the line info shows in the stack trace. I also made sure that the JVM is started with -Xint just to make sure the info is not erased as a optimization when the code is JIT compiled.

And most confusing: although all classes are loaded and instrumented the same, this is only true for some classes, not for all. This is the main reason, why I think this has got something to do with the JVM.

So my question is: does the JVM omit line info in the stack trace, if so when and how can I prevent this?

Edit: Just to make things clear: This is the class file of the source file I have in front of me, not of a 3rd party library. And as should be clear from above I tried hard to make sure the info is in the bytecode.

Edit: Now I even found an example where one StackTraceElement has line number info and another one hasn't and they are concerned with different methods from the same class !

This has to do with how the class file was compiled. Have a peek here:

http://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/javac.html

and look for the "debugging information" around the -g flag. If you add -g, your code will contain line numbers (and a lot of other useful information).

This won't retroactively add debug information to 3rd party libraries, I'm afraid. You'll have to see about getting the source, or getting debug builds from the vendor. I've found that this is usually not necessary.

I'm wondering if the lines reported (or not, as it were) in your stack trace were generated when ASM instrumented your classes. Since they were modified post-compile, any line numbers wouldn't appear in the class file, so they wouldn't be available to the class loader (or be reportable by javap). I don't have a lot of experience with run-time code generation, so it's just a guess, but maybe it's something you could consider.

Not all line numbers are available in the JVM. Some third party libraries may be compiled without line numbers, particularly non-open-source ones, and even some Java classes have protected source code that's doing encryption or some other protected logic. In short, not everything will always have line numbers.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM