This is an archive of the discontinued LLVM Phabricator instance.

[clang][debug] port clang-cl /JMC flag to ELF
ClosedPublic

Authored by ychen on Feb 15 2022, 6:24 PM.

Details

Summary

The motivation is to enable the MSVC-style JMC instrumentation usable by a ELF-based
debugger. Since there is no prior experience implementing JMC feature for ELF-based
debugger, it might be better to just reuse existing MSVC-style JMC instrumentation.
For debuggers that support both ELF&COFF (like lldb), the JMC implementation might
be shared between ELF&COFF. If this is found to inadequate, it is pretty low-cost
switching to alternatives.

Implementation:

  • The '-fjmc' is already a driver and cc1 flag. Wire it up for ELF in the driver.
  • Refactor the JMC instrumentation pass a little bit.
  • The ELF handling is different from MSVC in two places:
    • the flag section name is ".just.my.code" instead of ".msvcjmc"
    • the way default function is provided: MSVC uses /alternatename; ELF uses weak function.

Based on D118428.

Diff Detail

Event Timeline

ychen created this revision.Feb 15 2022, 6:24 PM
ychen requested review of this revision.Feb 15 2022, 6:24 PM
Herald added projects: Restricted Project, Restricted Project. · View Herald TranscriptFeb 15 2022, 6:24 PM

Not my usual wheelhouse, but since I'm here, here are some of my thoughts:

  • reusing the existing solution/code seems like a good idea -- no need to reinvent the wheel
  • how does that work, actually? How does it differentiate between "my" code and "code that happens to be compiled in the current CU" (e.g. the STL). What's the significance of the funky __XXXXXXXX_x@c symbols?
  • if the goal is to integrate this into lldb (and given that lldb currently does not support any feature like this), I'd recommend sending an RFC/heads up early, to identify possible issues
  • how does that work, actually? How does it differentiate between "my" code and "code that happens to be compiled in the current CU" (e.g. the STL). What's the significance of the funky __XXXXXXXX_x@c symbols?

The non-user code is specified by a config file (https://docs.microsoft.com/en-us/visualstudio/debugger/just-my-code?view=vs-2022#BKMK_CPP_Customize_call_stack_behavior). Then the debugger would know user/non-user code by looking at the debuginfo. The boolean __XXXXXXXX_x@c symbol has a one-to-one mapping to a source file. For all functions defined in the corresponding source file, it decides if a breakpoint would be hit. It is the JMC_flag in https://github.com/ojdkbuild/tools_toolchain_vs2017bt_1416/blob/master/VC/Tools/MSVC/14.16.27023/crt/src/vcruntime/debugger_jmc.c.

  • if the goal is to integrate this into lldb (and given that lldb currently does not support any feature like this), I'd recommend sending an RFC/heads up early, to identify possible issues

The goal is to make the feature usable by an ELF-based compiler(actually we have a downstream debugger that needed this. lldb/gdb as well). I think this could benefit upstream debuggers hence this patch. I'll send an RFC. Thanks.

ychen added a comment.Feb 28 2022, 2:23 PM

Gentle ping...

rnk added inline comments.Mar 4 2022, 10:40 AM
clang/lib/Driver/ToolChains/Clang.cpp
5396

Generally all flags have an fno- variant. Normally, this would be hasFlag(OPT_fjmc, OPT_fno_jmc, false), which handles the behavior of making the last flag win. Any reason not to set that up?

llvm/lib/CodeGen/JMCInstrumenter.cpp
177

This is a bit pedantic, but the idea is that this weak function will be overridden with a strong function, right? Technically, for that use case, weak linkage is the correct linkage. Because the JMC pass runs late after inlining, it is unlikely that this will ever cause issues in practice, but I think it expresses the intention better to use the linkage that matches the use case.

ODR linkage is supposed to indicate that all definitions must be functionally equivalent. It just turns out that the only real power that grants the optimizer is the ability to inline.

llvm/test/Instrumentation/JustMyCode/jmc-instrument-elf.ll
1–2

Please remove the REQUIRES line, this test should pass on Windows, and the other test should pass on Linux as well. Neither of these tests depend on anything from the system.

Herald added a project: Restricted Project. · View Herald TranscriptMar 4 2022, 10:40 AM
ychen added inline comments.Mar 4 2022, 12:54 PM
clang/lib/Driver/ToolChains/Clang.cpp
5396

I missed that. Before this port, fjmc is supposed to be used as cc1 option only. With this port, it is also a driver option now. I'll add the no-variant.

llvm/lib/CodeGen/JMCInstrumenter.cpp
177

Agreed. I'll change it to weak linkage.

llvm/test/Instrumentation/JustMyCode/jmc-instrument-elf.ll
1–2

Yeah, this is a little tricky. It is about the host rather than the target. The flag symbol name is computed using sys::path functions. It is different between Windows and Linux. For testing purposes, I need to anchor them to a specific system to check the result. I could've made this ; REQUIRES: system-windows and check the result, I thought it is more intuitive to test the ELF on Linux.

ychen updated this revision to Diff 413146.Mar 4 2022, 2:33 PM
  • Address Reid's comments
ychen marked 2 inline comments as done.Mar 4 2022, 2:34 PM

@rnk, thanks for taking a look. Patch updated.

rnk added inline comments.Mar 4 2022, 2:35 PM
llvm/lib/CodeGen/JMCInstrumenter.cpp
72

These sys::path calls introduce host-dependence, and that should be eliminated

llvm/test/Instrumentation/JustMyCode/jmc-instrument-elf.ll
1–2

That seems like a bug. LLVM optimization and code generation should not depend on the host. This is a requirement for distributed build systems, which may migrate inputs to other machines, cross compile, and expect the results to match local compilation.

rnk accepted this revision.Mar 4 2022, 2:37 PM

Looks like I hit submit too early...

I wanted to say the path thing is a pre-existing issue, and it seems reasonable to address that as a separate patch. If you don't have plans to do a follow up patch, please file a bug about it, and maybe I can hand it off to someone.

This revision is now accepted and ready to land.Mar 4 2022, 2:37 PM
ychen added inline comments.Mar 4 2022, 2:38 PM
llvm/test/Instrumentation/JustMyCode/jmc-instrument-elf.ll
1–2

The symbol names are host-dependent. It does not depend on the host to work correctly though. It works on both Windows and Linux.

rnk added inline comments.Mar 4 2022, 2:49 PM
llvm/test/Instrumentation/JustMyCode/jmc-instrument-elf.ll
1–2

Yes, you say they are host dependent, I see that, but I don't think that's a requirement. opt should be a pure function of its inputs. The paths are in the debug info, it shouldn't let the environment leak into the compilation.

ychen added inline comments.Mar 4 2022, 3:37 PM
llvm/test/Instrumentation/JustMyCode/jmc-instrument-elf.ll
1–2

Great point. This is not ideal in principle. For the distributed build, this may break if the remote and host compilation uses different environments like Windows/Linux. I'll create a follow-up patch.

ychen added inline comments.Mar 4 2022, 4:02 PM
llvm/test/Instrumentation/JustMyCode/jmc-instrument-elf.ll
1–2
This revision was landed with ongoing or failed builds.Mar 7 2022, 10:18 AM
This revision was automatically updated to reflect the committed changes.
thakis added a subscriber: thakis.Mar 7 2022, 11:31 AM

Looks like this breaks tests on mac and win:
http://45.33.8.238/win/54551/step_7.txt
http://45.33.8.238/macm1/29590/step_7.txt

Please take a look, and revert for now if it takes a while to fix.

ychen added a comment.Mar 7 2022, 11:41 AM

Looks like this breaks tests on mac and win:
http://45.33.8.238/win/54551/step_7.txt
http://45.33.8.238/macm1/29590/step_7.txt

Please take a look, and revert for now if it takes a while to fix.

Thanks for the report. I'm looking at it.

ychen added a comment.Mar 8 2022, 11:03 AM

Looks like this breaks tests on mac and win:
http://45.33.8.238/win/54551/step_7.txt
http://45.33.8.238/macm1/29590/step_7.txt

Please take a look, and revert for now if it takes a while to fix.

Thanks for the report. I'm looking at it.

Recommited as eddd94c27df609113af1d1b795d8483aa6dd662c