Re: RFR: 8242181: [Linux] Show source information when printing native stack traces in hs_err files [v5]

2022-03-30 Thread Christian Hagedorn
On Wed, 30 Mar 2022 06:35:27 GMT, Christian Hagedorn  
wrote:

>> Hi Christian,
>> 
>> this is impressive work. It's a big change, and I had a look at part of it. 
>> I'll continue tomorrow.
>> 
>> In general, I'm concerned with the use of both UL and ResourceArea in this 
>> code. I know the use of UL has been discussed, but still. Use of RA will 
>> prevent us from getting useful callstacks if we crash and Thread::current is 
>> NULL or invalid. I'd feel better if we were to consistently rely on an 
>> outside scratch buffer (like we usually do in error reporting). Even raw 
>> ::malloc would be better IMHO.
>> 
>> Another concern was safety, since this is a potential attack vector with 
>> manipulated Dwarf files, if someone manages to provove a crash. Maybe far 
>> fetched, but still. Would be good to get SonarCloud readings for this code 
>> e.g.
>> 
>> More remarks inline.
>> 
>> Cheers, Thomas
>
>> this is impressive work. It's a big change, and I had a look at part of it. 
>> I'll continue tomorrow.
> 
> Thanks a lot Thomas for your careful review! I'm in the process of working 
> through your comments and will come back with an update today or later this 
> week.
> 
>> In general, I'm concerned with the use of both UL and ResourceArea in this 
>> code. I know the use of UL has been discussed, but still. 
> 
> I agree that it is problematic but I think it would be good to keep some 
> logging around when later coming back to the parser code (and that's the only 
> reason I think that you ever want to turn these logs on). I can currently 
> think of two options:
> 
> - Leave UL in and just guard it with an additional new develop flag to 
> exclude the logs from unfiltered UL logging. This would allow us to kinda 
> accept the risks for debugging purposes. That's not really a good design 
> though but we could keep the log levels with their time stamps.
> - Replace all UL calls with `tty` and also guard them with a new develop flag 
> and play around with `Verbose` and `WizardMode` to keep the different log 
> levels. That's not great either but I think it's safer to use and we only 
> want the logs on rare occasions anyways - so it might be acceptable to use 
> these verbose flags even though we should generally get away from them.
> 
>> Use of RA will prevent us from getting useful callstacks if we crash and 
>> Thread::current is NULL or invalid. I'd feel better if we were to 
>> consistently rely on an outside scratch buffer (like we usually do in error 
>> reporting). Even raw ::malloc would be better IMHO.
> 
> The idea of a scratch buffer sounds good. I'll check if I can replace all the 
> `NEW_RESOURCE_ARRAY` usages with it.
>  
>> Another concern was safety, since this is a potential attack vector with 
>> manipulated Dwarf files, if someone manages to provove a crash. Maybe far 
>> fetched, but still. Would be good to get SonarCloud readings for this code 
>> e.g.
> 
> I was also concerned about that and I'm very thankful that you've spotted 
> some issues already! I think minimizing the risk of a potential attack should 
> be a top priority. We should definitely add some more checks. What do you 
> think about the usage of `_JVM_DWARF_PATH` to load a DWARF file? I'm not sure 
> how safe it is. I originally had it enabled for debug builds only.
> 
>> We see test errors on Linux ppcle and x64 in gtests:
> 
> Could you try running it with `-Xlog:dwarf=info/debug` in order to find out 
> why it failed? It might not have found the symbols. Is the JTreg test 
> `TestDwarf.java` working? But there is now another problem that since using 
> GCC 11.2 (change done for Oracle builds with 
> [JDK-8283057](https://bugs.openjdk.java.net/browse/JDK-8283057)), it emits 
> unsupported DWARF 5 for some DWARF sections, at least on my machine, which is 
> unfortunate. Maybe that's also the reason you see the failures if you use GCC 
> 11.2. Maybe we can mitigate this problem by forcing GCC to use DWARF 4 for 
> now. Could that be done by using the `-gdwarf` GCC flag? @erikj79
> 
>> We also see Problems in runtime/ErrorHandling and in 
>> jfr/jvm/TestDumpOnCrash. Mostly, these tests now have much longer runtimes 
>> (about factor 2). With TestDumpOnCrash, both the error file writer and the 
>> test itself timeouted on some of our slower machines.
> 
> Are these timeouts on ppcle and x64? We could also try to add 
> `-Xlog:dwarf=info/debug` to the runs to get some rough idea of the time 
> required to parse DWARF. I'll have a look at the these tests.
> 
> Thanks,
> Christian

> @chhagedorn
> 
> > There is still some code that could be shared though like opening a DWARF 
> > file with its checks or reading an LEB 128 etc. Might be worth to 
> > investigate further if the two implementations can be merged/reused to some 
> > extent. But I propose to file a separate RFE for that. What do you think?
> 
> Yeah, let's investigate about it in another RFE.
> 
> IMHO we can share some codes about DWARF between HotSpot 

Re: RFR: 8242181: [Linux] Show source information when printing native stack traces in hs_err files [v5]

2022-03-30 Thread Christian Hagedorn
On Mon, 28 Mar 2022 13:14:50 GMT, Thomas Stuefe  wrote:

> this is impressive work. It's a big change, and I had a look at part of it. 
> I'll continue tomorrow.

Thanks a lot Thomas for your careful review! I'm in the process of working 
through your comments and will come back with an update today or later this 
week.

> In general, I'm concerned with the use of both UL and ResourceArea in this 
> code. I know the use of UL has been discussed, but still. 

I agree that it is problematic but I think it would be good to keep some 
logging around when later coming back to the parser code (and that's the only 
reason I think that you ever want to turn these logs on). I can currently think 
of two options:

- Leave UL in and just guard it with an additional new develop flag to exclude 
the logs from unfiltered UL logging. This would allow us to kinda accept the 
risks for debugging purposes. That's not really a good design though but we 
could keep the log levels with their time stamps.
- Replace all UL calls with `tty` and also guard them with a new develop flag 
and play around with `Verbose` and `WizardMode` to keep the different log 
levels. That's not great either but I think it's safer to use and we only want 
the logs on rare occasions anyways - so it might be acceptable to use these 
verbose flags even though we should generally get away from them.

> Use of RA will prevent us from getting useful callstacks if we crash and 
> Thread::current is NULL or invalid. I'd feel better if we were to 
> consistently rely on an outside scratch buffer (like we usually do in error 
> reporting). Even raw ::malloc would be better IMHO.

The idea of a scratch buffer sounds good. I'll check if I can replace all the 
`NEW_RESOURCE_ARRAY` usages with it.
 
> Another concern was safety, since this is a potential attack vector with 
> manipulated Dwarf files, if someone manages to provove a crash. Maybe far 
> fetched, but still. Would be good to get SonarCloud readings for this code 
> e.g.

I was also concerned about that and I'm very thankful that you've spotted some 
issues already! I think minimizing the risk of a potential attack should be a 
top priority. We should definitely add some more checks. What do you think 
about the usage of `_JVM_DWARF_PATH` to load a DWARF file? I'm not sure how 
safe it is. I originally had it enabled for debug builds only.

> We see test errors on Linux ppcle and x64 in gtests:

Could you try running it with `-Xlog:dwarf=info/debug` in order to find out why 
it failed? It might not have found the symbols. Is the JTreg test 
`TestDwarf.java` working? But there is now another problem that since using GCC 
11.2 (change done for Oracle builds with 
[JDK-8283057](https://bugs.openjdk.java.net/browse/JDK-8283057)), it emits 
unsupported DWARF 5 for some DWARF sections, at least on my machine, which is 
unfortunate. Maybe that's also the reason you see the failures if you use GCC 
11.2. Maybe we can mitigate this problem by forcing GCC to use DWARF 4 for now. 
Could that be done by using the `-gdwarf` GCC flag? @erikj79

> We also see Problems in runtime/ErrorHandling and in jfr/jvm/TestDumpOnCrash. 
> Mostly, these tests now have much longer runtimes (about factor 2). With 
> TestDumpOnCrash, both the error file writer and the test itself timeouted on 
> some of our slower machines.

Are these timeouts on ppcle and x64? We could also try to add 
`-Xlog:dwarf=info/debug` to the runs to get some rough idea of the time 
required to parse DWARF. I'll have a look at the these tests.

Thanks,
Christian

-

PR: https://git.openjdk.java.net/jdk/pull/7126


Re: RFR: 8242181: [Linux] Show source information when printing native stack traces in hs_err files [v5]

2022-03-29 Thread Thomas Stuefe
On Mon, 28 Feb 2022 16:22:25 GMT, Christian Hagedorn  
wrote:

>> When printing the native stack trace on Linux (mostly done for hs_err 
>> files), it only prints the method with its parameters and a relative offset 
>> in the method:
>> 
>> Stack: [0x7f6e01739000,0x7f6e0183a000],  sp=0x7f6e01838110,  
>> free space=1020k
>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 
>> code)
>> V  [libjvm.so+0x620d86]  Compilation::~Compilation()+0x64
>> V  [libjvm.so+0x624b92]  Compiler::compile_method(ciEnv*, ciMethod*, int, 
>> bool, DirectiveSet*)+0xec
>> V  [libjvm.so+0x8303ef]  
>> CompileBroker::invoke_compiler_on_method(CompileTask*)+0x899
>> V  [libjvm.so+0x82f067]  CompileBroker::compiler_thread_loop()+0x3df
>> V  [libjvm.so+0x84f0d1]  CompilerThread::thread_entry(JavaThread*, 
>> JavaThread*)+0x69
>> V  [libjvm.so+0x1209329]  JavaThread::thread_main_inner()+0x15d
>> V  [libjvm.so+0x12091c9]  JavaThread::run()+0x167
>> V  [libjvm.so+0x1206ada]  Thread::call_run()+0x180
>> V  [libjvm.so+0x1012e55]  thread_native_entry(Thread*)+0x18f
>> 
>> This makes it sometimes difficult to see where exactly the methods were 
>> called from and sometimes almost impossible when there are multiple 
>> invocations of the same method within one method.
>> 
>> This patch improves this by providing source information (filename + line 
>> number) to the native stack traces on Linux similar to what's already done 
>> on Windows (see 
>> [JDK-8185712](https://bugs.openjdk.java.net/browse/JDK-8185712)):
>> 
>> Stack: [0x7f34fca18000,0x7f34fcb19000],  sp=0x7f34fcb17110,  
>> free space=1020k
>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 
>> code)
>> V  [libjvm.so+0x620d86]  Compilation::~Compilation()+0x64  
>> (c1_Compilation.cpp:607)
>> V  [libjvm.so+0x624b92]  Compiler::compile_method(ciEnv*, ciMethod*, int, 
>> bool, DirectiveSet*)+0xec  (c1_Compiler.cpp:250)
>> V  [libjvm.so+0x8303ef]  
>> CompileBroker::invoke_compiler_on_method(CompileTask*)+0x899  
>> (compileBroker.cpp:2291)
>> V  [libjvm.so+0x82f067]  CompileBroker::compiler_thread_loop()+0x3df  
>> (compileBroker.cpp:1966)
>> V  [libjvm.so+0x84f0d1]  CompilerThread::thread_entry(JavaThread*, 
>> JavaThread*)+0x69  (compilerThread.cpp:59)
>> V  [libjvm.so+0x1209329]  JavaThread::thread_main_inner()+0x15d  
>> (thread.cpp:1297)
>> V  [libjvm.so+0x12091c9]  JavaThread::run()+0x167  (thread.cpp:1280)
>> V  [libjvm.so+0x1206ada]  Thread::call_run()+0x180  (thread.cpp:358)
>> V  [libjvm.so+0x1012e55]  thread_native_entry(Thread*)+0x18f  
>> (os_linux.cpp:705)
>> 
>> For Linux, we need to parse the debug symbols which are generated by GCC in 
>> DWARF - a standardized debugging format. This patch adds support for DWARF 
>> 4, the default of GCC 10.x, for 32 and 64 bit architectures (tested with 
>> x86_32, x86_64 and AArch64). DWARF 5 is not supported as it was still 
>> experimental and not generated for HotSpot. However, newer GCC version may 
>> soon generate DWARF 5 by default in which case this parser either needs to 
>> be extended or the build of HotSpot configured to only emit DWARF 4. 
>> 
>> The code follows the parsing steps described in the official DWARF 4 spec: 
>> https://dwarfstd.org/doc/DWARF4.pdf
>> I added references to the corresponding sections throughout the code. 
>> However, I tried to explain the steps from the DWARF spec directly in the 
>> code (method names, comments etc.). This allows to follow the code without 
>> the need to actually deep dive into the spec. 
>> 
>> The comments at the `Dwarf` class in the `elf.hpp` file explain in more 
>> detail how a DWARF file is structured and how the parsing algorithm works to 
>> get to the filename and line number information. There are more class 
>> comments throughout the `elf.hpp` file about how different DWARF sections 
>> are structured and how the parsing algorithm needs to fetch the required 
>> information. Therefore, I will not repeat the exact workings of the 
>> algorithm here but refer to the code comments. I've tried to add as much 
>> information as possible to improve the readability.
>> 
>> Generally, I've tried to stay away from adding any assertions as this code 
>> is almost always executed when already processing a VM error. Instead, the 
>> DWARF parser aims to just exit gracefully and possibly omit source 
>> information for a stack frame instead of risking to stop writing the hs_err 
>> file when an assertion would have failed. To debug failures, `-Xlog:dwarf` 
>> can be used with `info`, `debug` or `trace` which provides logging messages 
>> throughout parsing. 
>> 
>> **Testing:**
>> Apart from manual testing, I've added two kinds of tests:
>> - A JTreg test: Spawns new VMs to let them crash in various ways. The test 
>> reads the created hs_err files to check if the DWARF parsing could correctly 
>> find the filename and line number. For normal HotSpot files, I could not 
>> check against hardcoded 

Re: RFR: 8242181: [Linux] Show source information when printing native stack traces in hs_err files [v5]

2022-03-29 Thread Thomas Stuefe
On Mon, 28 Feb 2022 16:22:25 GMT, Christian Hagedorn  
wrote:

>> When printing the native stack trace on Linux (mostly done for hs_err 
>> files), it only prints the method with its parameters and a relative offset 
>> in the method:
>> 
>> Stack: [0x7f6e01739000,0x7f6e0183a000],  sp=0x7f6e01838110,  
>> free space=1020k
>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 
>> code)
>> V  [libjvm.so+0x620d86]  Compilation::~Compilation()+0x64
>> V  [libjvm.so+0x624b92]  Compiler::compile_method(ciEnv*, ciMethod*, int, 
>> bool, DirectiveSet*)+0xec
>> V  [libjvm.so+0x8303ef]  
>> CompileBroker::invoke_compiler_on_method(CompileTask*)+0x899
>> V  [libjvm.so+0x82f067]  CompileBroker::compiler_thread_loop()+0x3df
>> V  [libjvm.so+0x84f0d1]  CompilerThread::thread_entry(JavaThread*, 
>> JavaThread*)+0x69
>> V  [libjvm.so+0x1209329]  JavaThread::thread_main_inner()+0x15d
>> V  [libjvm.so+0x12091c9]  JavaThread::run()+0x167
>> V  [libjvm.so+0x1206ada]  Thread::call_run()+0x180
>> V  [libjvm.so+0x1012e55]  thread_native_entry(Thread*)+0x18f
>> 
>> This makes it sometimes difficult to see where exactly the methods were 
>> called from and sometimes almost impossible when there are multiple 
>> invocations of the same method within one method.
>> 
>> This patch improves this by providing source information (filename + line 
>> number) to the native stack traces on Linux similar to what's already done 
>> on Windows (see 
>> [JDK-8185712](https://bugs.openjdk.java.net/browse/JDK-8185712)):
>> 
>> Stack: [0x7f34fca18000,0x7f34fcb19000],  sp=0x7f34fcb17110,  
>> free space=1020k
>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 
>> code)
>> V  [libjvm.so+0x620d86]  Compilation::~Compilation()+0x64  
>> (c1_Compilation.cpp:607)
>> V  [libjvm.so+0x624b92]  Compiler::compile_method(ciEnv*, ciMethod*, int, 
>> bool, DirectiveSet*)+0xec  (c1_Compiler.cpp:250)
>> V  [libjvm.so+0x8303ef]  
>> CompileBroker::invoke_compiler_on_method(CompileTask*)+0x899  
>> (compileBroker.cpp:2291)
>> V  [libjvm.so+0x82f067]  CompileBroker::compiler_thread_loop()+0x3df  
>> (compileBroker.cpp:1966)
>> V  [libjvm.so+0x84f0d1]  CompilerThread::thread_entry(JavaThread*, 
>> JavaThread*)+0x69  (compilerThread.cpp:59)
>> V  [libjvm.so+0x1209329]  JavaThread::thread_main_inner()+0x15d  
>> (thread.cpp:1297)
>> V  [libjvm.so+0x12091c9]  JavaThread::run()+0x167  (thread.cpp:1280)
>> V  [libjvm.so+0x1206ada]  Thread::call_run()+0x180  (thread.cpp:358)
>> V  [libjvm.so+0x1012e55]  thread_native_entry(Thread*)+0x18f  
>> (os_linux.cpp:705)
>> 
>> For Linux, we need to parse the debug symbols which are generated by GCC in 
>> DWARF - a standardized debugging format. This patch adds support for DWARF 
>> 4, the default of GCC 10.x, for 32 and 64 bit architectures (tested with 
>> x86_32, x86_64 and AArch64). DWARF 5 is not supported as it was still 
>> experimental and not generated for HotSpot. However, newer GCC version may 
>> soon generate DWARF 5 by default in which case this parser either needs to 
>> be extended or the build of HotSpot configured to only emit DWARF 4. 
>> 
>> The code follows the parsing steps described in the official DWARF 4 spec: 
>> https://dwarfstd.org/doc/DWARF4.pdf
>> I added references to the corresponding sections throughout the code. 
>> However, I tried to explain the steps from the DWARF spec directly in the 
>> code (method names, comments etc.). This allows to follow the code without 
>> the need to actually deep dive into the spec. 
>> 
>> The comments at the `Dwarf` class in the `elf.hpp` file explain in more 
>> detail how a DWARF file is structured and how the parsing algorithm works to 
>> get to the filename and line number information. There are more class 
>> comments throughout the `elf.hpp` file about how different DWARF sections 
>> are structured and how the parsing algorithm needs to fetch the required 
>> information. Therefore, I will not repeat the exact workings of the 
>> algorithm here but refer to the code comments. I've tried to add as much 
>> information as possible to improve the readability.
>> 
>> Generally, I've tried to stay away from adding any assertions as this code 
>> is almost always executed when already processing a VM error. Instead, the 
>> DWARF parser aims to just exit gracefully and possibly omit source 
>> information for a stack frame instead of risking to stop writing the hs_err 
>> file when an assertion would have failed. To debug failures, `-Xlog:dwarf` 
>> can be used with `info`, `debug` or `trace` which provides logging messages 
>> throughout parsing. 
>> 
>> **Testing:**
>> Apart from manual testing, I've added two kinds of tests:
>> - A JTreg test: Spawns new VMs to let them crash in various ways. The test 
>> reads the created hs_err files to check if the DWARF parsing could correctly 
>> find the filename and line number. For normal HotSpot files, I could not 
>> check against hardcoded 

Re: RFR: 8242181: [Linux] Show source information when printing native stack traces in hs_err files [v5]

2022-03-29 Thread Thomas Stuefe
On Mon, 28 Mar 2022 22:25:01 GMT, David Holmes  wrote:

>> src/hotspot/share/utilities/elfFile.cpp line 450:
>> 
>>> 448:   if (buf == nullptr) {
>>> 449: return false;
>>> 450:   }
>> 
>> I'd move this close to and local to where it is used.
>> 
>> Also, you seem to repeat the same pattern a lot "NEW_RESOURCE_ARRAY(n), if 
>> error return something". I'd factor this out to an utility function or 
>> utility macro, maybe one where you pass the error return value as macro 
>> parameter.
>
> Thomas's comment caught my attention in the email. NEW_RESOURCE_ARRAY aborts 
> the VM on OOM. Use NEW_RESOURCE_ARRAY_RETURN_NULL if you want to continue.

As I wrote in another comment, I'd rather we avoid RA altogether since it 
relies on Thread::current(), and we want to see callstacks even with 
Thread::current==NULL.

-

PR: https://git.openjdk.java.net/jdk/pull/7126


Re: RFR: 8242181: [Linux] Show source information when printing native stack traces in hs_err files [v5]

2022-03-28 Thread David Holmes
On Mon, 28 Mar 2022 12:58:20 GMT, Thomas Stuefe  wrote:

>> Christian Hagedorn has updated the pull request with a new target base due 
>> to a merge or a rebase. The pull request now contains 54 commits:
>> 
>>  - Updating some comments
>>  - Cleanup loading dwarf file and add summary
>>  - Review comments of first pass by Thomas except dwarf file loading
>>  - Merge branch 'master' into JDK-8242181
>>  - Make dwarf tag NOT_PRODUCT
>>  - Change log_* to log_develop_* and log_warning to log_develop_info
>>  - Update test/hotspot/jtreg/runtime/ErrorHandling/TestDwarf.java
>>
>>Co-authored-by: Erik Joelsson <37597443+erik...@users.noreply.github.com>
>>  - Update test/hotspot/jtreg/runtime/ErrorHandling/TestDwarf.java
>>
>>Co-authored-by: Erik Joelsson <37597443+erik...@users.noreply.github.com>
>>  - Better formatting of trace output
>>  - some code move and more cleanups
>>  - ... and 44 more: 
>> https://git.openjdk.java.net/jdk/compare/efd3967b...5bea4841
>
> src/hotspot/share/utilities/elfFile.cpp line 450:
> 
>> 448:   if (buf == nullptr) {
>> 449: return false;
>> 450:   }
> 
> I'd move this close to and local to where it is used.
> 
> Also, you seem to repeat the same pattern a lot "NEW_RESOURCE_ARRAY(n), if 
> error return something". I'd factor this out to an utility function or 
> utility macro, maybe one where you pass the error return value as macro 
> parameter.

Thomas's comment caught my attention in the email. NEW_RESOURCE_ARRAY aborts 
the VM on OOM. Use NEW_RESOURCE_ARRAY_RETURN_NULL if you want to continue.

-

PR: https://git.openjdk.java.net/jdk/pull/7126


Re: RFR: 8242181: [Linux] Show source information when printing native stack traces in hs_err files [v5]

2022-03-28 Thread Thomas Stuefe
On Mon, 28 Mar 2022 12:20:44 GMT, Thomas Stuefe  wrote:

>> Christian Hagedorn has updated the pull request with a new target base due 
>> to a merge or a rebase. The pull request now contains 54 commits:
>> 
>>  - Updating some comments
>>  - Cleanup loading dwarf file and add summary
>>  - Review comments of first pass by Thomas except dwarf file loading
>>  - Merge branch 'master' into JDK-8242181
>>  - Make dwarf tag NOT_PRODUCT
>>  - Change log_* to log_develop_* and log_warning to log_develop_info
>>  - Update test/hotspot/jtreg/runtime/ErrorHandling/TestDwarf.java
>>
>>Co-authored-by: Erik Joelsson <37597443+erik...@users.noreply.github.com>
>>  - Update test/hotspot/jtreg/runtime/ErrorHandling/TestDwarf.java
>>
>>Co-authored-by: Erik Joelsson <37597443+erik...@users.noreply.github.com>
>>  - Better formatting of trace output
>>  - some code move and more cleanups
>>  - ... and 44 more: 
>> https://git.openjdk.java.net/jdk/compare/efd3967b...5bea4841
>
> src/hotspot/share/utilities/elfFile.hpp line 217:
> 
>> 215:public:
>> 216: DwarfFilePath(const char* filename, char* buf, size_t buf_len) : 
>> _filename(filename), _path(buf), _path_len(buf_len) {
>> 217:   size_t offset = (strlen(filename) + 4) >> 2u;
> 
> Why not use align()? Would be more readable.

See also comments in load_dwarf_file(). I'd really be more happy with more 
verifications.

-

PR: https://git.openjdk.java.net/jdk/pull/7126


Re: RFR: 8242181: [Linux] Show source information when printing native stack traces in hs_err files [v5]

2022-03-28 Thread Thomas Stuefe
On Mon, 28 Feb 2022 16:22:25 GMT, Christian Hagedorn  
wrote:

>> When printing the native stack trace on Linux (mostly done for hs_err 
>> files), it only prints the method with its parameters and a relative offset 
>> in the method:
>> 
>> Stack: [0x7f6e01739000,0x7f6e0183a000],  sp=0x7f6e01838110,  
>> free space=1020k
>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 
>> code)
>> V  [libjvm.so+0x620d86]  Compilation::~Compilation()+0x64
>> V  [libjvm.so+0x624b92]  Compiler::compile_method(ciEnv*, ciMethod*, int, 
>> bool, DirectiveSet*)+0xec
>> V  [libjvm.so+0x8303ef]  
>> CompileBroker::invoke_compiler_on_method(CompileTask*)+0x899
>> V  [libjvm.so+0x82f067]  CompileBroker::compiler_thread_loop()+0x3df
>> V  [libjvm.so+0x84f0d1]  CompilerThread::thread_entry(JavaThread*, 
>> JavaThread*)+0x69
>> V  [libjvm.so+0x1209329]  JavaThread::thread_main_inner()+0x15d
>> V  [libjvm.so+0x12091c9]  JavaThread::run()+0x167
>> V  [libjvm.so+0x1206ada]  Thread::call_run()+0x180
>> V  [libjvm.so+0x1012e55]  thread_native_entry(Thread*)+0x18f
>> 
>> This makes it sometimes difficult to see where exactly the methods were 
>> called from and sometimes almost impossible when there are multiple 
>> invocations of the same method within one method.
>> 
>> This patch improves this by providing source information (filename + line 
>> number) to the native stack traces on Linux similar to what's already done 
>> on Windows (see 
>> [JDK-8185712](https://bugs.openjdk.java.net/browse/JDK-8185712)):
>> 
>> Stack: [0x7f34fca18000,0x7f34fcb19000],  sp=0x7f34fcb17110,  
>> free space=1020k
>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 
>> code)
>> V  [libjvm.so+0x620d86]  Compilation::~Compilation()+0x64  
>> (c1_Compilation.cpp:607)
>> V  [libjvm.so+0x624b92]  Compiler::compile_method(ciEnv*, ciMethod*, int, 
>> bool, DirectiveSet*)+0xec  (c1_Compiler.cpp:250)
>> V  [libjvm.so+0x8303ef]  
>> CompileBroker::invoke_compiler_on_method(CompileTask*)+0x899  
>> (compileBroker.cpp:2291)
>> V  [libjvm.so+0x82f067]  CompileBroker::compiler_thread_loop()+0x3df  
>> (compileBroker.cpp:1966)
>> V  [libjvm.so+0x84f0d1]  CompilerThread::thread_entry(JavaThread*, 
>> JavaThread*)+0x69  (compilerThread.cpp:59)
>> V  [libjvm.so+0x1209329]  JavaThread::thread_main_inner()+0x15d  
>> (thread.cpp:1297)
>> V  [libjvm.so+0x12091c9]  JavaThread::run()+0x167  (thread.cpp:1280)
>> V  [libjvm.so+0x1206ada]  Thread::call_run()+0x180  (thread.cpp:358)
>> V  [libjvm.so+0x1012e55]  thread_native_entry(Thread*)+0x18f  
>> (os_linux.cpp:705)
>> 
>> For Linux, we need to parse the debug symbols which are generated by GCC in 
>> DWARF - a standardized debugging format. This patch adds support for DWARF 
>> 4, the default of GCC 10.x, for 32 and 64 bit architectures (tested with 
>> x86_32, x86_64 and AArch64). DWARF 5 is not supported as it was still 
>> experimental and not generated for HotSpot. However, newer GCC version may 
>> soon generate DWARF 5 by default in which case this parser either needs to 
>> be extended or the build of HotSpot configured to only emit DWARF 4. 
>> 
>> The code follows the parsing steps described in the official DWARF 4 spec: 
>> https://dwarfstd.org/doc/DWARF4.pdf
>> I added references to the corresponding sections throughout the code. 
>> However, I tried to explain the steps from the DWARF spec directly in the 
>> code (method names, comments etc.). This allows to follow the code without 
>> the need to actually deep dive into the spec. 
>> 
>> The comments at the `Dwarf` class in the `elf.hpp` file explain in more 
>> detail how a DWARF file is structured and how the parsing algorithm works to 
>> get to the filename and line number information. There are more class 
>> comments throughout the `elf.hpp` file about how different DWARF sections 
>> are structured and how the parsing algorithm needs to fetch the required 
>> information. Therefore, I will not repeat the exact workings of the 
>> algorithm here but refer to the code comments. I've tried to add as much 
>> information as possible to improve the readability.
>> 
>> Generally, I've tried to stay away from adding any assertions as this code 
>> is almost always executed when already processing a VM error. Instead, the 
>> DWARF parser aims to just exit gracefully and possibly omit source 
>> information for a stack frame instead of risking to stop writing the hs_err 
>> file when an assertion would have failed. To debug failures, `-Xlog:dwarf` 
>> can be used with `info`, `debug` or `trace` which provides logging messages 
>> throughout parsing. 
>> 
>> **Testing:**
>> Apart from manual testing, I've added two kinds of tests:
>> - A JTreg test: Spawns new VMs to let them crash in various ways. The test 
>> reads the created hs_err files to check if the DWARF parsing could correctly 
>> find the filename and line number. For normal HotSpot files, I could not 
>> check against hardcoded 

Re: RFR: 8242181: [Linux] Show source information when printing native stack traces in hs_err files [v5]

2022-03-28 Thread Yasumasa Suenaga
On Mon, 28 Feb 2022 16:22:25 GMT, Christian Hagedorn  
wrote:

>> When printing the native stack trace on Linux (mostly done for hs_err 
>> files), it only prints the method with its parameters and a relative offset 
>> in the method:
>> 
>> Stack: [0x7f6e01739000,0x7f6e0183a000],  sp=0x7f6e01838110,  
>> free space=1020k
>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 
>> code)
>> V  [libjvm.so+0x620d86]  Compilation::~Compilation()+0x64
>> V  [libjvm.so+0x624b92]  Compiler::compile_method(ciEnv*, ciMethod*, int, 
>> bool, DirectiveSet*)+0xec
>> V  [libjvm.so+0x8303ef]  
>> CompileBroker::invoke_compiler_on_method(CompileTask*)+0x899
>> V  [libjvm.so+0x82f067]  CompileBroker::compiler_thread_loop()+0x3df
>> V  [libjvm.so+0x84f0d1]  CompilerThread::thread_entry(JavaThread*, 
>> JavaThread*)+0x69
>> V  [libjvm.so+0x1209329]  JavaThread::thread_main_inner()+0x15d
>> V  [libjvm.so+0x12091c9]  JavaThread::run()+0x167
>> V  [libjvm.so+0x1206ada]  Thread::call_run()+0x180
>> V  [libjvm.so+0x1012e55]  thread_native_entry(Thread*)+0x18f
>> 
>> This makes it sometimes difficult to see where exactly the methods were 
>> called from and sometimes almost impossible when there are multiple 
>> invocations of the same method within one method.
>> 
>> This patch improves this by providing source information (filename + line 
>> number) to the native stack traces on Linux similar to what's already done 
>> on Windows (see 
>> [JDK-8185712](https://bugs.openjdk.java.net/browse/JDK-8185712)):
>> 
>> Stack: [0x7f34fca18000,0x7f34fcb19000],  sp=0x7f34fcb17110,  
>> free space=1020k
>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 
>> code)
>> V  [libjvm.so+0x620d86]  Compilation::~Compilation()+0x64  
>> (c1_Compilation.cpp:607)
>> V  [libjvm.so+0x624b92]  Compiler::compile_method(ciEnv*, ciMethod*, int, 
>> bool, DirectiveSet*)+0xec  (c1_Compiler.cpp:250)
>> V  [libjvm.so+0x8303ef]  
>> CompileBroker::invoke_compiler_on_method(CompileTask*)+0x899  
>> (compileBroker.cpp:2291)
>> V  [libjvm.so+0x82f067]  CompileBroker::compiler_thread_loop()+0x3df  
>> (compileBroker.cpp:1966)
>> V  [libjvm.so+0x84f0d1]  CompilerThread::thread_entry(JavaThread*, 
>> JavaThread*)+0x69  (compilerThread.cpp:59)
>> V  [libjvm.so+0x1209329]  JavaThread::thread_main_inner()+0x15d  
>> (thread.cpp:1297)
>> V  [libjvm.so+0x12091c9]  JavaThread::run()+0x167  (thread.cpp:1280)
>> V  [libjvm.so+0x1206ada]  Thread::call_run()+0x180  (thread.cpp:358)
>> V  [libjvm.so+0x1012e55]  thread_native_entry(Thread*)+0x18f  
>> (os_linux.cpp:705)
>> 
>> For Linux, we need to parse the debug symbols which are generated by GCC in 
>> DWARF - a standardized debugging format. This patch adds support for DWARF 
>> 4, the default of GCC 10.x, for 32 and 64 bit architectures (tested with 
>> x86_32, x86_64 and AArch64). DWARF 5 is not supported as it was still 
>> experimental and not generated for HotSpot. However, newer GCC version may 
>> soon generate DWARF 5 by default in which case this parser either needs to 
>> be extended or the build of HotSpot configured to only emit DWARF 4. 
>> 
>> The code follows the parsing steps described in the official DWARF 4 spec: 
>> https://dwarfstd.org/doc/DWARF4.pdf
>> I added references to the corresponding sections throughout the code. 
>> However, I tried to explain the steps from the DWARF spec directly in the 
>> code (method names, comments etc.). This allows to follow the code without 
>> the need to actually deep dive into the spec. 
>> 
>> The comments at the `Dwarf` class in the `elf.hpp` file explain in more 
>> detail how a DWARF file is structured and how the parsing algorithm works to 
>> get to the filename and line number information. There are more class 
>> comments throughout the `elf.hpp` file about how different DWARF sections 
>> are structured and how the parsing algorithm needs to fetch the required 
>> information. Therefore, I will not repeat the exact workings of the 
>> algorithm here but refer to the code comments. I've tried to add as much 
>> information as possible to improve the readability.
>> 
>> Generally, I've tried to stay away from adding any assertions as this code 
>> is almost always executed when already processing a VM error. Instead, the 
>> DWARF parser aims to just exit gracefully and possibly omit source 
>> information for a stack frame instead of risking to stop writing the hs_err 
>> file when an assertion would have failed. To debug failures, `-Xlog:dwarf` 
>> can be used with `info`, `debug` or `trace` which provides logging messages 
>> throughout parsing. 
>> 
>> **Testing:**
>> Apart from manual testing, I've added two kinds of tests:
>> - A JTreg test: Spawns new VMs to let them crash in various ways. The test 
>> reads the created hs_err files to check if the DWARF parsing could correctly 
>> find the filename and line number. For normal HotSpot files, I could not 
>> check against hardcoded 

Re: RFR: 8242181: [Linux] Show source information when printing native stack traces in hs_err files [v5]

2022-03-28 Thread Christian Hagedorn
On Mon, 28 Mar 2022 08:44:10 GMT, Thomas Stuefe  wrote:

> > Ping - may I get another review for this change?
> 
> I'll take a look later today or tomorrow. This is nice stuff, I'm looking 
> forward to having it upstream.

That's great, thanks Thomas!

-

PR: https://git.openjdk.java.net/jdk/pull/7126


Re: RFR: 8242181: [Linux] Show source information when printing native stack traces in hs_err files [v5]

2022-03-28 Thread Thomas Stuefe
On Mon, 28 Mar 2022 06:46:30 GMT, Christian Hagedorn  
wrote:

> Ping - may I get another review for this change?

I'll take a look later today or tomorrow. This is nice stuff, I'm looking 
forward to having it upstream.

-

PR: https://git.openjdk.java.net/jdk/pull/7126


Re: RFR: 8242181: [Linux] Show source information when printing native stack traces in hs_err files [v5]

2022-03-28 Thread Christian Hagedorn
On Mon, 28 Feb 2022 16:22:25 GMT, Christian Hagedorn  
wrote:

>> When printing the native stack trace on Linux (mostly done for hs_err 
>> files), it only prints the method with its parameters and a relative offset 
>> in the method:
>> 
>> Stack: [0x7f6e01739000,0x7f6e0183a000],  sp=0x7f6e01838110,  
>> free space=1020k
>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 
>> code)
>> V  [libjvm.so+0x620d86]  Compilation::~Compilation()+0x64
>> V  [libjvm.so+0x624b92]  Compiler::compile_method(ciEnv*, ciMethod*, int, 
>> bool, DirectiveSet*)+0xec
>> V  [libjvm.so+0x8303ef]  
>> CompileBroker::invoke_compiler_on_method(CompileTask*)+0x899
>> V  [libjvm.so+0x82f067]  CompileBroker::compiler_thread_loop()+0x3df
>> V  [libjvm.so+0x84f0d1]  CompilerThread::thread_entry(JavaThread*, 
>> JavaThread*)+0x69
>> V  [libjvm.so+0x1209329]  JavaThread::thread_main_inner()+0x15d
>> V  [libjvm.so+0x12091c9]  JavaThread::run()+0x167
>> V  [libjvm.so+0x1206ada]  Thread::call_run()+0x180
>> V  [libjvm.so+0x1012e55]  thread_native_entry(Thread*)+0x18f
>> 
>> This makes it sometimes difficult to see where exactly the methods were 
>> called from and sometimes almost impossible when there are multiple 
>> invocations of the same method within one method.
>> 
>> This patch improves this by providing source information (filename + line 
>> number) to the native stack traces on Linux similar to what's already done 
>> on Windows (see 
>> [JDK-8185712](https://bugs.openjdk.java.net/browse/JDK-8185712)):
>> 
>> Stack: [0x7f34fca18000,0x7f34fcb19000],  sp=0x7f34fcb17110,  
>> free space=1020k
>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 
>> code)
>> V  [libjvm.so+0x620d86]  Compilation::~Compilation()+0x64  
>> (c1_Compilation.cpp:607)
>> V  [libjvm.so+0x624b92]  Compiler::compile_method(ciEnv*, ciMethod*, int, 
>> bool, DirectiveSet*)+0xec  (c1_Compiler.cpp:250)
>> V  [libjvm.so+0x8303ef]  
>> CompileBroker::invoke_compiler_on_method(CompileTask*)+0x899  
>> (compileBroker.cpp:2291)
>> V  [libjvm.so+0x82f067]  CompileBroker::compiler_thread_loop()+0x3df  
>> (compileBroker.cpp:1966)
>> V  [libjvm.so+0x84f0d1]  CompilerThread::thread_entry(JavaThread*, 
>> JavaThread*)+0x69  (compilerThread.cpp:59)
>> V  [libjvm.so+0x1209329]  JavaThread::thread_main_inner()+0x15d  
>> (thread.cpp:1297)
>> V  [libjvm.so+0x12091c9]  JavaThread::run()+0x167  (thread.cpp:1280)
>> V  [libjvm.so+0x1206ada]  Thread::call_run()+0x180  (thread.cpp:358)
>> V  [libjvm.so+0x1012e55]  thread_native_entry(Thread*)+0x18f  
>> (os_linux.cpp:705)
>> 
>> For Linux, we need to parse the debug symbols which are generated by GCC in 
>> DWARF - a standardized debugging format. This patch adds support for DWARF 
>> 4, the default of GCC 10.x, for 32 and 64 bit architectures (tested with 
>> x86_32, x86_64 and AArch64). DWARF 5 is not supported as it was still 
>> experimental and not generated for HotSpot. However, newer GCC version may 
>> soon generate DWARF 5 by default in which case this parser either needs to 
>> be extended or the build of HotSpot configured to only emit DWARF 4. 
>> 
>> The code follows the parsing steps described in the official DWARF 4 spec: 
>> https://dwarfstd.org/doc/DWARF4.pdf
>> I added references to the corresponding sections throughout the code. 
>> However, I tried to explain the steps from the DWARF spec directly in the 
>> code (method names, comments etc.). This allows to follow the code without 
>> the need to actually deep dive into the spec. 
>> 
>> The comments at the `Dwarf` class in the `elf.hpp` file explain in more 
>> detail how a DWARF file is structured and how the parsing algorithm works to 
>> get to the filename and line number information. There are more class 
>> comments throughout the `elf.hpp` file about how different DWARF sections 
>> are structured and how the parsing algorithm needs to fetch the required 
>> information. Therefore, I will not repeat the exact workings of the 
>> algorithm here but refer to the code comments. I've tried to add as much 
>> information as possible to improve the readability.
>> 
>> Generally, I've tried to stay away from adding any assertions as this code 
>> is almost always executed when already processing a VM error. Instead, the 
>> DWARF parser aims to just exit gracefully and possibly omit source 
>> information for a stack frame instead of risking to stop writing the hs_err 
>> file when an assertion would have failed. To debug failures, `-Xlog:dwarf` 
>> can be used with `info`, `debug` or `trace` which provides logging messages 
>> throughout parsing. 
>> 
>> **Testing:**
>> Apart from manual testing, I've added two kinds of tests:
>> - A JTreg test: Spawns new VMs to let them crash in various ways. The test 
>> reads the created hs_err files to check if the DWARF parsing could correctly 
>> find the filename and line number. For normal HotSpot files, I could not 
>> check against hardcoded 

Re: RFR: 8242181: [Linux] Show source information when printing native stack traces in hs_err files [v5]

2022-03-11 Thread Christian Hagedorn
On Mon, 28 Feb 2022 16:22:25 GMT, Christian Hagedorn  
wrote:

>> When printing the native stack trace on Linux (mostly done for hs_err 
>> files), it only prints the method with its parameters and a relative offset 
>> in the method:
>> 
>> Stack: [0x7f6e01739000,0x7f6e0183a000],  sp=0x7f6e01838110,  
>> free space=1020k
>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 
>> code)
>> V  [libjvm.so+0x620d86]  Compilation::~Compilation()+0x64
>> V  [libjvm.so+0x624b92]  Compiler::compile_method(ciEnv*, ciMethod*, int, 
>> bool, DirectiveSet*)+0xec
>> V  [libjvm.so+0x8303ef]  
>> CompileBroker::invoke_compiler_on_method(CompileTask*)+0x899
>> V  [libjvm.so+0x82f067]  CompileBroker::compiler_thread_loop()+0x3df
>> V  [libjvm.so+0x84f0d1]  CompilerThread::thread_entry(JavaThread*, 
>> JavaThread*)+0x69
>> V  [libjvm.so+0x1209329]  JavaThread::thread_main_inner()+0x15d
>> V  [libjvm.so+0x12091c9]  JavaThread::run()+0x167
>> V  [libjvm.so+0x1206ada]  Thread::call_run()+0x180
>> V  [libjvm.so+0x1012e55]  thread_native_entry(Thread*)+0x18f
>> 
>> This makes it sometimes difficult to see where exactly the methods were 
>> called from and sometimes almost impossible when there are multiple 
>> invocations of the same method within one method.
>> 
>> This patch improves this by providing source information (filename + line 
>> number) to the native stack traces on Linux similar to what's already done 
>> on Windows (see 
>> [JDK-8185712](https://bugs.openjdk.java.net/browse/JDK-8185712)):
>> 
>> Stack: [0x7f34fca18000,0x7f34fcb19000],  sp=0x7f34fcb17110,  
>> free space=1020k
>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 
>> code)
>> V  [libjvm.so+0x620d86]  Compilation::~Compilation()+0x64  
>> (c1_Compilation.cpp:607)
>> V  [libjvm.so+0x624b92]  Compiler::compile_method(ciEnv*, ciMethod*, int, 
>> bool, DirectiveSet*)+0xec  (c1_Compiler.cpp:250)
>> V  [libjvm.so+0x8303ef]  
>> CompileBroker::invoke_compiler_on_method(CompileTask*)+0x899  
>> (compileBroker.cpp:2291)
>> V  [libjvm.so+0x82f067]  CompileBroker::compiler_thread_loop()+0x3df  
>> (compileBroker.cpp:1966)
>> V  [libjvm.so+0x84f0d1]  CompilerThread::thread_entry(JavaThread*, 
>> JavaThread*)+0x69  (compilerThread.cpp:59)
>> V  [libjvm.so+0x1209329]  JavaThread::thread_main_inner()+0x15d  
>> (thread.cpp:1297)
>> V  [libjvm.so+0x12091c9]  JavaThread::run()+0x167  (thread.cpp:1280)
>> V  [libjvm.so+0x1206ada]  Thread::call_run()+0x180  (thread.cpp:358)
>> V  [libjvm.so+0x1012e55]  thread_native_entry(Thread*)+0x18f  
>> (os_linux.cpp:705)
>> 
>> For Linux, we need to parse the debug symbols which are generated by GCC in 
>> DWARF - a standardized debugging format. This patch adds support for DWARF 
>> 4, the default of GCC 10.x, for 32 and 64 bit architectures (tested with 
>> x86_32, x86_64 and AArch64). DWARF 5 is not supported as it was still 
>> experimental and not generated for HotSpot. However, newer GCC version may 
>> soon generate DWARF 5 by default in which case this parser either needs to 
>> be extended or the build of HotSpot configured to only emit DWARF 4. 
>> 
>> The code follows the parsing steps described in the official DWARF 4 spec: 
>> https://dwarfstd.org/doc/DWARF4.pdf
>> I added references to the corresponding sections throughout the code. 
>> However, I tried to explain the steps from the DWARF spec directly in the 
>> code (method names, comments etc.). This allows to follow the code without 
>> the need to actually deep dive into the spec. 
>> 
>> The comments at the `Dwarf` class in the `elf.hpp` file explain in more 
>> detail how a DWARF file is structured and how the parsing algorithm works to 
>> get to the filename and line number information. There are more class 
>> comments throughout the `elf.hpp` file about how different DWARF sections 
>> are structured and how the parsing algorithm needs to fetch the required 
>> information. Therefore, I will not repeat the exact workings of the 
>> algorithm here but refer to the code comments. I've tried to add as much 
>> information as possible to improve the readability.
>> 
>> Generally, I've tried to stay away from adding any assertions as this code 
>> is almost always executed when already processing a VM error. Instead, the 
>> DWARF parser aims to just exit gracefully and possibly omit source 
>> information for a stack frame instead of risking to stop writing the hs_err 
>> file when an assertion would have failed. To debug failures, `-Xlog:dwarf` 
>> can be used with `info`, `debug` or `trace` which provides logging messages 
>> throughout parsing. 
>> 
>> **Testing:**
>> Apart from manual testing, I've added two kinds of tests:
>> - A JTreg test: Spawns new VMs to let them crash in various ways. The test 
>> reads the created hs_err files to check if the DWARF parsing could correctly 
>> find the filename and line number. For normal HotSpot files, I could not 
>> check against hardcoded 

Re: RFR: 8242181: [Linux] Show source information when printing native stack traces in hs_err files [v5]

2022-03-11 Thread Thomas Schatzl
On Mon, 28 Feb 2022 16:22:25 GMT, Christian Hagedorn  
wrote:

>> When printing the native stack trace on Linux (mostly done for hs_err 
>> files), it only prints the method with its parameters and a relative offset 
>> in the method:
>> 
>> Stack: [0x7f6e01739000,0x7f6e0183a000],  sp=0x7f6e01838110,  
>> free space=1020k
>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 
>> code)
>> V  [libjvm.so+0x620d86]  Compilation::~Compilation()+0x64
>> V  [libjvm.so+0x624b92]  Compiler::compile_method(ciEnv*, ciMethod*, int, 
>> bool, DirectiveSet*)+0xec
>> V  [libjvm.so+0x8303ef]  
>> CompileBroker::invoke_compiler_on_method(CompileTask*)+0x899
>> V  [libjvm.so+0x82f067]  CompileBroker::compiler_thread_loop()+0x3df
>> V  [libjvm.so+0x84f0d1]  CompilerThread::thread_entry(JavaThread*, 
>> JavaThread*)+0x69
>> V  [libjvm.so+0x1209329]  JavaThread::thread_main_inner()+0x15d
>> V  [libjvm.so+0x12091c9]  JavaThread::run()+0x167
>> V  [libjvm.so+0x1206ada]  Thread::call_run()+0x180
>> V  [libjvm.so+0x1012e55]  thread_native_entry(Thread*)+0x18f
>> 
>> This makes it sometimes difficult to see where exactly the methods were 
>> called from and sometimes almost impossible when there are multiple 
>> invocations of the same method within one method.
>> 
>> This patch improves this by providing source information (filename + line 
>> number) to the native stack traces on Linux similar to what's already done 
>> on Windows (see 
>> [JDK-8185712](https://bugs.openjdk.java.net/browse/JDK-8185712)):
>> 
>> Stack: [0x7f34fca18000,0x7f34fcb19000],  sp=0x7f34fcb17110,  
>> free space=1020k
>> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 
>> code)
>> V  [libjvm.so+0x620d86]  Compilation::~Compilation()+0x64  
>> (c1_Compilation.cpp:607)
>> V  [libjvm.so+0x624b92]  Compiler::compile_method(ciEnv*, ciMethod*, int, 
>> bool, DirectiveSet*)+0xec  (c1_Compiler.cpp:250)
>> V  [libjvm.so+0x8303ef]  
>> CompileBroker::invoke_compiler_on_method(CompileTask*)+0x899  
>> (compileBroker.cpp:2291)
>> V  [libjvm.so+0x82f067]  CompileBroker::compiler_thread_loop()+0x3df  
>> (compileBroker.cpp:1966)
>> V  [libjvm.so+0x84f0d1]  CompilerThread::thread_entry(JavaThread*, 
>> JavaThread*)+0x69  (compilerThread.cpp:59)
>> V  [libjvm.so+0x1209329]  JavaThread::thread_main_inner()+0x15d  
>> (thread.cpp:1297)
>> V  [libjvm.so+0x12091c9]  JavaThread::run()+0x167  (thread.cpp:1280)
>> V  [libjvm.so+0x1206ada]  Thread::call_run()+0x180  (thread.cpp:358)
>> V  [libjvm.so+0x1012e55]  thread_native_entry(Thread*)+0x18f  
>> (os_linux.cpp:705)
>> 
>> For Linux, we need to parse the debug symbols which are generated by GCC in 
>> DWARF - a standardized debugging format. This patch adds support for DWARF 
>> 4, the default of GCC 10.x, for 32 and 64 bit architectures (tested with 
>> x86_32, x86_64 and AArch64). DWARF 5 is not supported as it was still 
>> experimental and not generated for HotSpot. However, newer GCC version may 
>> soon generate DWARF 5 by default in which case this parser either needs to 
>> be extended or the build of HotSpot configured to only emit DWARF 4. 
>> 
>> The code follows the parsing steps described in the official DWARF 4 spec: 
>> https://dwarfstd.org/doc/DWARF4.pdf
>> I added references to the corresponding sections throughout the code. 
>> However, I tried to explain the steps from the DWARF spec directly in the 
>> code (method names, comments etc.). This allows to follow the code without 
>> the need to actually deep dive into the spec. 
>> 
>> The comments at the `Dwarf` class in the `elf.hpp` file explain in more 
>> detail how a DWARF file is structured and how the parsing algorithm works to 
>> get to the filename and line number information. There are more class 
>> comments throughout the `elf.hpp` file about how different DWARF sections 
>> are structured and how the parsing algorithm needs to fetch the required 
>> information. Therefore, I will not repeat the exact workings of the 
>> algorithm here but refer to the code comments. I've tried to add as much 
>> information as possible to improve the readability.
>> 
>> Generally, I've tried to stay away from adding any assertions as this code 
>> is almost always executed when already processing a VM error. Instead, the 
>> DWARF parser aims to just exit gracefully and possibly omit source 
>> information for a stack frame instead of risking to stop writing the hs_err 
>> file when an assertion would have failed. To debug failures, `-Xlog:dwarf` 
>> can be used with `info`, `debug` or `trace` which provides logging messages 
>> throughout parsing. 
>> 
>> **Testing:**
>> Apart from manual testing, I've added two kinds of tests:
>> - A JTreg test: Spawns new VMs to let them crash in various ways. The test 
>> reads the created hs_err files to check if the DWARF parsing could correctly 
>> find the filename and line number. For normal HotSpot files, I could not 
>> check against hardcoded 

Re: RFR: 8242181: [Linux] Show source information when printing native stack traces in hs_err files [v5]

2022-02-28 Thread Christian Hagedorn
> When printing the native stack trace on Linux (mostly done for hs_err files), 
> it only prints the method with its parameters and a relative offset in the 
> method:
> 
> Stack: [0x7f6e01739000,0x7f6e0183a000],  sp=0x7f6e01838110,  free 
> space=1020k
> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 
> code)
> V  [libjvm.so+0x620d86]  Compilation::~Compilation()+0x64
> V  [libjvm.so+0x624b92]  Compiler::compile_method(ciEnv*, ciMethod*, int, 
> bool, DirectiveSet*)+0xec
> V  [libjvm.so+0x8303ef]  
> CompileBroker::invoke_compiler_on_method(CompileTask*)+0x899
> V  [libjvm.so+0x82f067]  CompileBroker::compiler_thread_loop()+0x3df
> V  [libjvm.so+0x84f0d1]  CompilerThread::thread_entry(JavaThread*, 
> JavaThread*)+0x69
> V  [libjvm.so+0x1209329]  JavaThread::thread_main_inner()+0x15d
> V  [libjvm.so+0x12091c9]  JavaThread::run()+0x167
> V  [libjvm.so+0x1206ada]  Thread::call_run()+0x180
> V  [libjvm.so+0x1012e55]  thread_native_entry(Thread*)+0x18f
> 
> This makes it sometimes difficult to see where exactly the methods were 
> called from and sometimes almost impossible when there are multiple 
> invocations of the same method within one method.
> 
> This patch improves this by providing source information (filename + line 
> number) to the native stack traces on Linux similar to what's already done on 
> Windows (see [JDK-8185712](https://bugs.openjdk.java.net/browse/JDK-8185712)):
> 
> Stack: [0x7f34fca18000,0x7f34fcb19000],  sp=0x7f34fcb17110,  free 
> space=1020k
> Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native 
> code)
> V  [libjvm.so+0x620d86]  Compilation::~Compilation()+0x64  
> (c1_Compilation.cpp:607)
> V  [libjvm.so+0x624b92]  Compiler::compile_method(ciEnv*, ciMethod*, int, 
> bool, DirectiveSet*)+0xec  (c1_Compiler.cpp:250)
> V  [libjvm.so+0x8303ef]  
> CompileBroker::invoke_compiler_on_method(CompileTask*)+0x899  
> (compileBroker.cpp:2291)
> V  [libjvm.so+0x82f067]  CompileBroker::compiler_thread_loop()+0x3df  
> (compileBroker.cpp:1966)
> V  [libjvm.so+0x84f0d1]  CompilerThread::thread_entry(JavaThread*, 
> JavaThread*)+0x69  (compilerThread.cpp:59)
> V  [libjvm.so+0x1209329]  JavaThread::thread_main_inner()+0x15d  
> (thread.cpp:1297)
> V  [libjvm.so+0x12091c9]  JavaThread::run()+0x167  (thread.cpp:1280)
> V  [libjvm.so+0x1206ada]  Thread::call_run()+0x180  (thread.cpp:358)
> V  [libjvm.so+0x1012e55]  thread_native_entry(Thread*)+0x18f  
> (os_linux.cpp:705)
> 
> For Linux, we need to parse the debug symbols which are generated by GCC in 
> DWARF - a standardized debugging format. This patch adds support for DWARF 4, 
> the default of GCC 10.x, for 32 and 64 bit architectures (tested with x86_32, 
> x86_64 and AArch64). DWARF 5 is not supported as it was still experimental 
> and not generated for HotSpot. However, newer GCC version may soon generate 
> DWARF 5 by default in which case this parser either needs to be extended or 
> the build of HotSpot configured to only emit DWARF 4. 
> 
> The code follows the parsing steps described in the official DWARF 4 spec: 
> https://dwarfstd.org/doc/DWARF4.pdf
> I added references to the corresponding sections throughout the code. 
> However, I tried to explain the steps from the DWARF spec directly in the 
> code (method names, comments etc.). This allows to follow the code without 
> the need to actually deep dive into the spec. 
> 
> The comments at the `Dwarf` class in the `elf.hpp` file explain in more 
> detail how a DWARF file is structured and how the parsing algorithm works to 
> get to the filename and line number information. There are more class 
> comments throughout the `elf.hpp` file about how different DWARF sections are 
> structured and how the parsing algorithm needs to fetch the required 
> information. Therefore, I will not repeat the exact workings of the algorithm 
> here but refer to the code comments. I've tried to add as much information as 
> possible to improve the readability.
> 
> Generally, I've tried to stay away from adding any assertions as this code is 
> almost always executed when already processing a VM error. Instead, the DWARF 
> parser aims to just exit gracefully and possibly omit source information for 
> a stack frame instead of risking to stop writing the hs_err file when an 
> assertion would have failed. To debug failures, `-Xlog:dwarf` can be used 
> with `info`, `debug` or `trace` which provides logging messages throughout 
> parsing. 
> 
> **Testing:**
> Apart from manual testing, I've added two kinds of tests:
> - A JTreg test: Spawns new VMs to let them crash in various ways. The test 
> reads the created hs_err files to check if the DWARF parsing could correctly 
> find the filename and line number. For normal HotSpot files, I could not 
> check against hardcoded filenames and line numbers as they are subject to 
> change (especially line number can quickly become different). I therefore 
> just added some sanity