This is an archive of the discontinued LLVM Phabricator instance.

[lldb] Set COFF module ABI from default triple and make it an option
ClosedPublic

Authored by alvinhochun on Jun 4 2022, 5:55 AM.

Details

Summary

PE/COFF can use either MSVC or GNU (MinGW) ABI for C++ code, however
LLDB had defaulted to MSVC implicitly with no way to override it. This
causes issues when debugging modules built with the GNU ABI, sometimes
even crashes.

This changes the PE/COFF plugin to set the module triple according to
the default target triple used to build LLDB. If the default target
triple is Windows and a valid environment is specified, then this
environment will be used for the module spec. This not only works for
MSVC and GNU, but also other environments.

A new setting, plugin.object-file.pe-coff.abi, has been added to
allow overriding this default ABI.

Diff Detail

Event Timeline

alvinhochun created this revision.Jun 4 2022, 5:55 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 4 2022, 5:55 AM
Herald added a subscriber: mstorsjo. · View Herald Transcript

Added tests

alvinhochun published this revision for review.Jun 5 2022, 3:41 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 5 2022, 3:41 AM

Fixed tests

Changed test requirement to be more accurate

Fixed tests again

This changes the PE/COFF and PDB plugins to set the module triple according to the default target triple used to build LLDB.

I'm missing some context here but using triple used when *building* lldb seems to conflict with the idea that the same lldb (client at least) can be used to debug many architectures.

Or is this not a concern because remote debugging is not a thing for Windows? For instance, is it possible that I'm on Linux with some AArch64 linux targeted lldb trying to remote debug a windows system. If the default triple is the best signal you've got then fair enough I guess just wanted to check there wasn't some more dynamic way to get it.

And I assume PE/COFF have no embedded flag in them to indicate this ABI?

This changes the PE/COFF and PDB plugins to set the module triple according to the default target triple used to build LLDB.

I'm missing some context here but using triple used when *building* lldb seems to conflict with the idea that the same lldb (client at least) can be used to debug many architectures.

Yes, that's true. The idea here is that when doing local debugging in either the mingw or msvc ecosystems, the flavour of the lldb build itself could be a decent hint - but it's not indeed not a correct and faultproof fix.

Or is this not a concern because remote debugging is not a thing for Windows? For instance, is it possible that I'm on Linux with some AArch64 linux targeted lldb trying to remote debug a windows system. If the default triple is the best signal you've got then fair enough I guess just wanted to check there wasn't some more dynamic way to get it.

And I assume PE/COFF have no embedded flag in them to indicate this ABI?

No, there's no flag for that. Mingw and MSVC environment binaries are quite the same.

(Qt Creator tries to do some similar heuristics to guess which ABI a binary uses, by looking at e.g. linker version numbers in the binary, to deduce whether a binary has been linked with GNU ld.bfd or MS link.exe - but when it comes to LLD, that logic falls apart. A more complex heuristic that can be used is e.g. looking at the list of DLLs that a binary links against, but that's also much more complex and also not entirely faultproof.)

@alvinhochun has got another patch in progress - https://reviews.llvm.org/D127053 (which isn't yet submitted for review as it lacks tests), which tries to decude the same based on whether a binary contains dwarf debug info.

That's more fault proof, but is also not an entirely complete fix - while finding dwarf debug sections mostly can imply using the itanium C++ ABI, you can also use PDB files with itanium C++ ABI (i.e. in mingw setups). It's less common but still a viable scenario. And reversely, I think I've heard about special cases where people use dwarf debug info with MSVC-ecosystem builds too...

So in short, what would be needed is a good enough heuristic that works for the vast majority of cases, and an option that lets users specify it for the cases that can't easily be autodetected.

This changes the PE/COFF and PDB plugins to set the module triple according to the default target triple used to build LLDB.

I'm missing some context here but using triple used when *building* lldb seems to conflict with the idea that the same lldb (client at least) can be used to debug many architectures.

Yes, that's true. The idea here is that when doing local debugging in either the mingw or msvc ecosystems, the flavour of the lldb build itself could be a decent hint - but it's not indeed not a correct and faultproof fix.

Yes, the aim is to at least have a default that at least works natively for the default target in local debugging. Before this change, C++ debugging for mingw target just doesn't work at all from what I understand so far.

@alvinhochun has got another patch in progress - https://reviews.llvm.org/D127053 (which isn't yet submitted for review as it lacks tests), which tries to decude the same based on whether a binary contains dwarf debug info.

That's more fault proof, but is also not an entirely complete fix - while finding dwarf debug sections mostly can imply using the itanium C++ ABI, you can also use PDB files with itanium C++ ABI (i.e. in mingw setups). It's less common but still a viable scenario. And reversely, I think I've heard about special cases where people use dwarf debug info with MSVC-ecosystem builds too...

So in short, what would be needed is a good enough heuristic that works for the vast majority of cases, and an option that lets users specify it for the cases that can't easily be autodetected.

I'm feeling wishy-washy on that patch because of the reason you stated. It may still be a good heuristic, but I think having an option to specify the ABI is a requirement before that patch can be landed.

I still don't have a clue how I can make it an option. It seems impossible to pass the option into ObjectFilePECOFF::GetModuleSpecifications cleanly.

There is an arch setting to target create but I doubt passing the whole triple there will make a difference (truncated to arch only at best).

Platforms do have settings so you could try adding something to remote-windows or presumably host when run on Windows. How you plumb that into where you need it I don't know.

(lldb) settings show platform.plugin.qemu-user.architecture
platform.plugin.qemu-user.architecture (string) =

I won't have time to comment much more but Omair might be able to help.

Also you might want to look at how the apple platforms select their ABI if you haven't already. If the answer is "with a flag in the object file" then oh well, but perhaps they have an override in there you could crib from.

Thanks for the hint. I think I can add a setting, say plugin.object-file.pe-coff.abi. It needs some plumbing but should be doable.

alvinhochun retitled this revision from [lldb] Set COFF and PDB module env from default target triple to [lldb] Set COFF module ABI from default triple and make it an option.
alvinhochun edited the summary of this revision. (Show Details)

Removed the changes for PDB, I don't think they actually affect anything.

Added a new setting plugin.object-file.pe-coff.abi to allow overriding the default ABI.

I am not fully familiar with PE/COFF but lets try to get this merged. For starters I have a couple of questions here:

  1. This rev apparently assumes x86_64 only but what about Arm/AArch64?
  2. If we have DLLs what abi setting they ll follow the one set by the user or default which may be MSVC?
  3. Is there anything in PE/COFF header information that can serve is a good guess for the underlying ABI.
  4. What more information can we get from debug info in this case? DWARF may not be a good guess as we can generate it for MSVC abi as well.

I am not fully familiar with PE/COFF but lets try to get this merged. For starters I have a couple of questions here:

  1. This rev apparently assumes x86_64 only but what about Arm/AArch64?

Where do you get that impression? This should all be architecture independent (or done in the same way for all architectures).

  1. If we have DLLs what abi setting they ll follow the one set by the user or default which may be MSVC?

Here, all DLLs are expected to use the same ABI (either the implicit one based on the LLDB build). D127234 is a follow-up that allows you to set a specific ABI choice per DLL.

  1. Is there anything in PE/COFF header information that can serve is a good guess for the underlying ABI.

No, there's no such hint. It's possible to make heuristic guesses based on e.g. what DLLs they import, but it's all guesses, possibly brittle. Having an option allows you to get it right even for the cases where the default is wrong.

  1. What more information can we get from debug info in this case? DWARF may not be a good guess as we can generate it for MSVC abi as well.

Exactly, one could use presence of DWARF as a heuristic hint for this, but it's not always right (you can use PDB for mingw uses too, and DWARF for msvc abi too in uncommon cases).

Thanks @mstorsjo for answering for me.

  1. What more information can we get from debug info in this case? DWARF may not be a good guess as we can generate it for MSVC abi as well.

Exactly, one could use presence of DWARF as a heuristic hint for this, but it's not always right (you can use PDB for mingw uses too, and DWARF for msvc abi too in uncommon cases).

I suppose we may try to look for mangled names and identify which name mangling scheme was used (MSVC vs Itanium ABI)? Though I am not keen on implementing it myself.

  1. This rev apparently assumes x86_64 only but what about Arm/AArch64?

Where do you get that impression? This should all be architecture independent (or done in the same way for all architectures).

Sorry I just brushed over the code and saw x86_64 specifc obj files in tests.

This looks good to me and I also gave this change a test on AArch64/Windows Surface X pro. No regressions. LGTM

omjavaid accepted this revision.Jun 9 2022, 2:00 AM
This revision is now accepted and ready to land.Jun 9 2022, 2:00 AM

Rebased patch