Implement core dump debugging for PPC64le.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
We were quite successful in the past in creating tiny core files to test these register contexts. Could you take a look at test/testcases/functionalities/postmortem/elf-core/make-core.sh to see if you can do the same for your architecture?
source/Plugins/Process/Utility/RegisterContextPOSIX_ppc64le.h | ||
---|---|---|
23 ↗ | (On Diff #121719) | delete this ? |
source/Plugins/Process/elf-core/ThreadElfCore.h | ||
183 ↗ | (On Diff #121719) | gpregset and fpregset sound fairly generic, but these other two sound really architecture specific. Since ThreadElfCore does not really do anything with these, just pass them to the register context, I'm thinking that we could just have a map of all register sets (something like DenseMap<uint32_t, DataExtractor>). Then we can just pass that to the register context constructor, and let it figure out what to do with it. What do you think? |
source/Plugins/Process/elf-core/ThreadElfCore.h | ||
---|---|---|
183 ↗ | (On Diff #121719) | That sounds like a good idea to me. |
I'm not sure what's the problem with backtracing without more info, but the nice thing about core files is that you can open a ppc and x86 one side by side and see how for do you get before things start to diverge. The interesting commands you can start with are "image lookup" (to see if you can find symbols properly), "image show-unwind" (to see the unwind plans) and "log enable lldb unwind && bt" (to see backtracing in action). This is what I get for the x86_64 core file (you should be able to see the same thing yourself):
(lldb) bt * thread #1, name = 'a.out', stop reason = signal SIGSEGV * frame #0: 0x000000000040011c linux-x86_64.out`bar(boom=0x0000000000000000) at main.c:4 frame #1: 0x0000000000400142 linux-x86_64.out`foo(boom=0x0000000000000000, boomer=(linux-x86_64.out`bar at main.c:2)) at main.c:10 frame #2: 0x000000000040015f linux-x86_64.out`_start at main.c:16 (lldb) image lookup -n bar 1 match found in /usr/local/google/home/labath/ll/lldb/test/testcases/functionalities/postmortem/elf-core/linux-x86_64.out: Address: linux-x86_64.out[0x000000000040010c] (linux-x86_64.out..text + 0) Summary: linux-x86_64.out`bar at main.c:2 (lldb) image show-unwind -n bar UNWIND PLANS for linux-x86_64.out`bar (start addr 0x40010c) Asynchronous (not restricted to call-sites) UnwindPlan is 'assembly insn profiling' Synchronous (restricted to call-sites) UnwindPlan is 'eh_frame CFI' Fast UnwindPlan is 'x86_64 default unwind plan' Assembly language inspection UnwindPlan: This UnwindPlan originally sourced from assembly insn profiling This UnwindPlan is sourced from the compiler: no. This UnwindPlan is valid at all instruction locations: yes. Address range of this UnwindPlan: [linux-x86_64.out..text + 0-0x0000000000000015) row[0]: 0: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] row[1]: 1: CFA=rsp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] row[2]: 4: CFA=rbp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] row[3]: 20: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8] eh_frame UnwindPlan: This UnwindPlan originally sourced from eh_frame CFI This UnwindPlan is sourced from the compiler: yes. This UnwindPlan is valid at all instruction locations: no. Address range of this UnwindPlan: [linux-x86_64.out..text + 0-0x0000000000000015) row[0]: 0: CFA=rsp +8 => rip=[CFA-8] row[1]: 1: CFA=rsp+16 => rbp=[CFA-16] rip=[CFA-8] row[2]: 4: CFA=rbp+16 => rbp=[CFA-16] rip=[CFA-8] row[3]: 20: CFA=rsp +8 => rbp=[CFA-16] rip=[CFA-8] Fast UnwindPlan: This UnwindPlan originally sourced from x86_64 default unwind plan This UnwindPlan is sourced from the compiler: no. This UnwindPlan is valid at all instruction locations: no. row[0]: 0: CFA=rbp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] Arch default UnwindPlan: This UnwindPlan originally sourced from x86_64 default unwind plan This UnwindPlan is sourced from the compiler: no. This UnwindPlan is valid at all instruction locations: no. row[0]: 0: CFA=rbp+16 => rbp=[CFA-16] rsp=CFA+0 rip=[CFA-8] Arch default at entry point UnwindPlan: This UnwindPlan originally sourced from x86_64 at-func-entry default This UnwindPlan is sourced from the compiler: no. This UnwindPlan is valid at all instruction locations: not specified. row[0]: 0: CFA=rsp +8 => rsp=CFA+0 rip=[CFA-8]
source/Plugins/Process/elf-core/ProcessElfCore.cpp | ||
---|---|---|
659 ↗ | (On Diff #122224) | I don't think we should make up new constants for the map indices, when we already have the NT_*** constants. You just need to move the constants to a header, so that you can use them from other files. The general purpose registers are the only ones that don't have a special constant, but we can probably agree to use NT_PRSTATUS for this, as that's where we're plucking them from anyway. |
718 ↗ | (On Diff #122224) | The good thing about these maps is that you don't have to check for the architecture here. You can just store this unconditionally there, and leave it up to the consumer to decide if he wants to make use of it. |
source/Plugins/Process/elf-core/RegisterContextPOSIXCore_ppc64le.h | ||
26 ↗ | (On Diff #122224) | The DenseMap isn't exactly cheap to copy. You should probably pass a (constant) reference here. |
Thank you. I've just noticed a couple of details we should address.
source/Plugins/Process/elf-core/elf-core-enums.h | ||
---|---|---|
1 ↗ | (On Diff #122239) | Please update the file name here and add header guards. |
11 ↗ | (On Diff #122239) | I'm sorry for the back and forth, but since we're already moving these, I think we should also put these into a linux namespace, as these are really linux-specific constants (except the NT_OPENBSD_*** ones, which should obviously get a namespace of their own (namespace OPENBSD { enum {NT_PROCINFO = ...}; })). |
Looks good, thank you. Just please make sure you change the file name at top of the new header file and add inclusion guards.
source/Plugins/Process/elf-core/elf-core-enums.h | ||
---|---|---|
1 ↗ | (On Diff #122239) | I think you've missed this one. |
I have fixed the backtrace issue.
The lr register was in a wrong position in RegisterInfos_ppc64le.h ,
Could you, please, submit these changes, @labath ?
Thanks! ;)
source/Plugins/Process/elf-core/elf-core-enums.h | ||
---|---|---|
14 ↗ | (On Diff #122879) | No namespace here? |
source/Plugins/Process/elf-core/elf-core-enums.h | ||
---|---|---|
14 ↗ | (On Diff #122879) | I think these constants are used for multiple OSs. |
source/Plugins/Process/elf-core/elf-core-enums.h | ||
---|---|---|
14 ↗ | (On Diff #122879) | There is rumor that they came from SVR4.. but I don't have the specs to make sure. Multiple in this case does not mean "all". This is not true for at least NetBSD. |
source/Plugins/Process/elf-core/elf-core-enums.h | ||
---|---|---|
14 ↗ | (On Diff #122879) | I can remove these constants and modify the first "if" in ParseThreadContextsFromNoteSegment to: if (((note.n_type == LINUX::NT_PRSTATUS || note.n_type == FREEBSD::NT_PRSTATUS) && have_prstatus) || ((note.n_type == LINUX::NT_PRPSINFO || note.n_type == FREEBSD::NT_PRPSINFO) && have_prpsinfo)) { assert(thread_data->gpregset.GetByteSize() > 0); What do you think? |
source/Plugins/Process/elf-core/elf-core-enums.h | ||
---|---|---|
14 ↗ | (On Diff #122879) | I propose to put NT_PRSTATUS, NT_PRFPREG, NT_PRPSINFO into this namespace and call it SVR4. SmartOS uses the same values. |
source/Plugins/Process/elf-core/elf-core-enums.h | ||
---|---|---|
14 ↗ | (On Diff #122879) | With the addition of all the bsd variants, the note parsing code has grown pretty big. My plan was to refactor it a bit after this is committed. I wanted to split it into two stages: first we just determine the OS from the notes; and then we dispatch to an appropriate os-specific function to do the actual parsing (with each function just using the NT constants from its own namespace). If you agree with that direction then I propose to go with the LINUX::NT_PRSTATUS || FREEBSD::NT_PRSTATUS proposed by alexandreyy in the interim. |
Also, I have trouble downloading the core file from phabricator. Alexandre, can you sent them to me directly?
source/Plugins/Process/elf-core/elf-core-enums.h | ||
---|---|---|
14 ↗ | (On Diff #122879) | Sounds good. |
source/Plugins/Process/elf-core/elf-core-enums.h | ||
---|---|---|
14 ↗ | (On Diff #122879) | Yes, that is probably the right approach. In binutils the note parsing code switches on the note name ("FreeBSD" vs "NetBSD" vs "CORE" vs "Linux", etc.) and then inside name-specific functions switches on the note type. I've been adding support for more notes to GDB for FreeBSD and ended up splitting out a handler for "FreeBSD" notes inline with this approach. Even notes with the same type (NT_PRSTATUS, etc.) have different layouts across OS's. |