Debugging clang with debugger breakpoints?

Hi All,

I want to understand some parts of ‘clang' by setting debug breakpoints.

I have successfully done so with “llc” but I found that debugger breakpoints do not work for ‘clang’

The apparent cause is that the clang code is run as a child process which is created in the ‘Execute' function of ‘Program.inc'. The debugger stops fine at breakpoints set on the main thread, but breakpoints do not work for any code that is executed as the child process. I am compiling with Xcode in case this makes a difference.

Thanks in advance for any help.

John

Run clang with -### to get the underlying command line (the one that has the first argument “-cc1”) and then run that command under the debugger instead.

Hi David,

Thank you for your help. Please, can you elaborate on this?. The command line that I get with -### starts with this:

clang version 9.0.1 (https://github.com/llvm/llvm-project.git 6e38ee067b8fa08792f551fb565bbb8ada4864b1)
Target: msp430
Thread model: posix
InstalledDir: /Users/joan/LLVM-9/llvm-project/build/Debug/bin
“/Users/joan/LLVM-9/llvm-project/build/Debug/bin/clang” “-cc1” “-triple” “msp430” “-emit-llvm” “-disable-free” “-main-file-name” “main.c” “-mrelocation-model” “static” “-mthread-model” “posix” “-fmath-errno” “-masm-verbose” “-mconstructor-aliases” “-nostdsysteminc” “-dwarf-column-info” “-debugger-tuning=gdb” “-target-linker-version” “305” “-momit-leaf-frame-pointer” “-coverage-notes-file” “/Users/joan/Documents-Local/Relay/RelayNou/main.gcno” “-resource-dir” “/Users/joan/LLVM-9/llvm-project/build/Debug/lib/clang/9.0.1” “-internal-isystem” “/Users/joan/LLVM-9/llvm-project/build/Debug/bin/…/msp430/include” “-Oz” “-fdebug-compilation-dir” “/Users/joan/Documents-Local/Relay/RelayNou” “-ferror-limit” “19” “-fmessage-length” “224” “-fobjc-runtime=gcc” “-fdiagnostics-show-option” “-fcolor-diagnostics” “-vectorize-slp” “-faddrsig” “-o” “main.ll” “-x” “c” “main.c”

So what should I set on the debugger?

Thanks

John

that command:

“/Users/joan/LLVM-9/llvm-project/build/Debug/bin/clang” “-cc1” “-triple” “msp430” “-emit-llvm” “-disable-free” “-main-file-name” “main.c” “-mrelocation-model” “static” “-mthread-model” “posix” “-fmath-errno” “-masm-verbose” “-mconstructor-aliases” “-nostdsysteminc” “-dwarf-column-info” “-debugger-tuning=gdb” “-target-linker-version” “305” “-momit-leaf-frame-pointer” “-coverage-notes-file” “/Users/joan/Documents-Local/Relay/RelayNou/main.gcno” “-resource-dir” “/Users/joan/LLVM-9/llvm-project/build/Debug/lib/clang/9.0.1” “-internal-isystem” “/Users/joan/LLVM-9/llvm-project/build/Debug/bin/…/msp430/include” “-Oz” “-fdebug-compilation-dir” “/Users/joan/Documents-Local/Relay/RelayNou” “-ferror-limit” “19” “-fmessage-length” “224” “-fobjc-runtime=gcc” “-fdiagnostics-show-option” “-fcolor-diagnostics” “-vectorize-slp” “-faddrsig” “-o” “main.ll” “-x” “c” “main.c”

Or wherever you had: -emit-llvm -S -g main.c (or something like that)
You now have: “-cc1” “-triple” “msp430” “-emit-llvm” “-disable-free” “-main-file-name” “main.c” “-mrelocation-model” “static” “-mthread-model” “posix” “-fmath-errno” “-masm-verbose” “-mconstructor-aliases” “-nostdsysteminc” “-dwarf-column-info” “-debugger-tuning=gdb” “-target-linker-version” “305” “-momit-leaf-frame-pointer” “-coverage-notes-file” “/Users/joan/Documents-Local/Relay/RelayNou/main.gcno” “-resource-dir” “/Users/joan/LLVM-9/llvm-project/build/Debug/lib/clang/9.0.1” “-internal-isystem” “/Users/joan/LLVM-9/llvm-project/build/Debug/bin/…/msp430/include” “-Oz” “-fdebug-compilation-dir” “/Users/joan/Documents-Local/Relay/RelayNou” “-ferror-limit” “19” “-fmessage-length” “224” “-fobjc-runtime=gcc” “-fdiagnostics-show-option” “-fcolor-diagnostics” “-vectorize-slp” “-faddrsig” “-o” “main.ll” “-x” “c” “main.c”

Hi David,

Thank you for your patience but I still don’t get it: I don’t see how that is a “command”, as it’s just a list of strings that state command options.

I know how to use the debugger, this is what I attempt to debug:

clang --target=msp430 -emit-llvm -c -S -Oz main.c

The debugger works fine, but only on the main thread. However breakpoints do not work with the code that was invoked as a child process with posix_spawn

The call to posix_spawn happens in file “Program.inc” on the ‘Execute’ function. The actual call is this

Err = posix_spawn(&PID, Program.str().c_str(), FileActions,
/attrp/ nullptr, const_cast<char **>(Argv),
const_cast<char **>(Envp));

the variable Program.str() contains "/Users/joan/LLVM-9/llvm-project/build/Debug/bin/clang” at this point, which I got with a breakpoint set at that point.

HOWEVER, any code that is run under that child process is not seen by the debugger.

I hope my issue is clearer now.

Thanks anyway.

John

Hi David,

Thank you for your patience but I still don’t get it: I don’t see how that is a “command”, as it’s just a list of strings that state command options.

I know how to use the debugger, this is what I attempt to debug:

clang --target=msp430 -emit-llvm -c -S -Oz main.c

OK, so wherever you have that ^ you should replace it with this /

clang “-cc1” “-triple” “msp430” “-emit-llvm” “-disable-free” “-main-file-name” “main.c” “-mrelocation-model” “static” “-mthread-model” “posix” “-fmath-errno” “-masm-verbose” “-mconstructor-aliases” “-nostdsysteminc” “-dwarf-column-info” “-debugger-tuning=gdb” “-target-linker-version” “305” “-momit-leaf-frame-pointer” “-coverage-notes-file” “/Users/joan/Documents-Local/Relay/RelayNou/main.gcno” “-resource-dir” “/Users/joan/LLVM-9/llvm-project/build/Debug/lib/clang/9.0.1” “-internal-isystem” “/Users/joan/LLVM-9/llvm-project/build/Debug/bin/…/msp430/include” “-Oz” “-fdebug-compilation-dir” “/Users/joan/Documents-Local/Relay/RelayNou” “-ferror-limit” “19” “-fmessage-length” “224” “-fobjc-runtime=gcc” “-fdiagnostics-show-option” “-fcolor-diagnostics” “-vectorize-slp” “-faddrsig” “-o” “main.ll” “-x” “c” “main.c”

It’s just a ton of command line arguments, but it’s not fundamentally different from the command you were already debugging - it’s clang with some command line arguments.

This clang command (the one with the first argument of -cc1) will not invoke a child process - this is the command that the clang command you ran would run as its child process. So it’s stripping off that layer so you can debug the underlying command/child process.

Hi David,

Thank you for your patience but I still don’t get it: I don’t see how that is a “command”, as it’s just a list of strings that state command options.

This is the output you pasted after running the command:

“/Users/joan/LLVM-9/llvm-project/build/Debug/bin/clang” “-cc1” “-triple” “msp430” “-emit-llvm” “-disable-free” “-main-file-name” “main.c” “-mrelocation-model” “static” “-mthread-model” “posix” “-fmath-errno” “-masm-verbose” “-mconstructor-aliases” “-nostdsysteminc” “-dwarf-column-info” “-debugger-tuning=gdb” “-target-linker-version” “305” “-momit-leaf-frame-pointer” “-coverage-notes-file” “/Users/joan/Documents-Local/Relay/RelayNou/main.gcno” “-resource-dir” “/Users/joan/LLVM-9/llvm-project/build/Debug/lib/clang/9.0.1” “-internal-isystem” “/Users/joan/LLVM-9/llvm-project/build/Debug/bin/…/msp430/include” “-Oz” “-fdebug-compilation-dir” “/Users/joan/Documents-Local/Relay/RelayNou” “-ferror-limit” “19” “-fmessage-length” “224” “-fobjc-runtime=gcc” “-fdiagnostics-show-option” “-fcolor-diagnostics” “-vectorize-slp” “-faddrsig” “-o” “main.ll” “-x” “c” “main.c”

Yes it is a list of strings. But the first string “/Users/joan/LLVM-9/llvm-project/build/Debug/bin/clang” is a command. The rest are arguments. So you should set your debugger to run this command:

“/Users/joan/LLVM-9/llvm-project/build/Debug/bin/clang”

with these arguments:

“-cc1” “-triple” “msp430” “-emit-llvm” “-disable-free” “-main-file-name” “main.c” “-mrelocation-model” “static” “-mthread-model” “posix” “-fmath-errno” “-masm-verbose” “-mconstructor-aliases” “-nostdsysteminc” “-dwarf-column-info” “-debugger-tuning=gdb” “-target-linker-version” “305” “-momit-leaf-frame-pointer” “-coverage-notes-file” “/Users/joan/Documents-Local/Relay/RelayNou/main.gcno” “-resource-dir” “/Users/joan/LLVM-9/llvm-project/build/Debug/lib/clang/9.0.1” “-internal-isystem” “/Users/joan/LLVM-9/llvm-project/build/Debug/bin/…/msp430/include” “-Oz” “-fdebug-compilation-dir” “/Users/joan/Documents-Local/Relay/RelayNou” “-ferror-limit” “19” “-fmessage-length” “224” “-fobjc-runtime=gcc” “-fdiagnostics-show-option” “-fcolor-diagnostics” “-vectorize-slp” “-faddrsig” “-o” “main.ll” “-x” “c” “main.c”

Does that make sense?

Hi David,

I understand what you say, but have you actually read my messages? I don’t think so,

Anyway, I will repost the question in case someone else can help.

Thanks

John

You hit Reply on my email but then addressed David. So I want to make sure you saw my suggestion. Let me know if you tried that and/or whether or not it solved your problem.

Zach

Sorry Zach, my apologies.

I understood now what you mean. I tried and it works!.

But now I found that LLVM_DEBUG statements and other output to the console doesn’t show. How do I get that back?.

Thanks

John

I’m not very familiar with this macro, as it seems to be new, but looking at llvm/include/llvm/Support/Debug.h it has this comment:

// In particular, just wrap your code with the LLVM_DEBUG() macro, and it will
// be enabled automatically if you specify ‘-debug’ on the command-line.
// LLVM_DEBUG() requires the DEBUG_TYPE macro to be defined.

So, perhaps you should try adding -debug to your command line and seeing if that fixes the problem.

If that doesn’t fix it, someone else may need to help as I’m not familiar with this issue specifically.

Hi David,

I understand now what you mean, and it worked. I replied already to someone else. Please accept my apologies as I misread a message before.

Thanks for your help.

John.

Hi Zach,

I appreciate that. The -debug option is apparently not known in this context, this is what the console pops up immediately:

[0;1;31merror: [0munknown argument: ‘-debug’[0m
Program ended with exit code: 1

I believe this is now a more general issue because all sort of output to the console is missing, not only LLVM_DEBUG() macro statements. It seems to me that I need to redirect console output to the ide console somehow. This is apparently done automatically when debugging the main thread in the usual way, but it’s not working in this case. Still, having working breakpoints and debug variables is a great improvement. So thanks for that.

John.

I assume you need -mllvm -debug

Zhang

Joan Lluch via llvm-dev <llvm-dev@lists.llvm.org> writes:

Hi All,

I want to understand some parts of ‘clang' by setting debug breakpoints.

I have successfully done so with “llc” but I found that debugger breakpoints do not work for ‘clang’

The apparent cause is that the clang code is run as a child process
which is created in the ‘Execute' function of ‘Program.inc'. The
debugger stops fine at breakpoints set on the main thread, but
breakpoints do not work for any code that is executed as the child
process. I am compiling with Xcode in case this makes a difference.

David provided one answer but if your debugger supports it, an easier
way is to set the debugger to follow child processes. With gdb it would
be "set follow-fork-mode child".

                 -David

Hi David,

I’m using the default Xcode debugger which happens to be Apple’s version of LLDB. Is there something equivalent for it?.

Thanks

John

Joan Lluch <joan.lluch@icloud.com> writes:

I’m using the default Xcode debugger which happens to be Apple’s
version of LLDB. Is there something equivalent for it?.

A really old SO post indicates not:

That may very well have changed since, I don't know. I don't use LLDB
at the moment.

                    -David

I have the same problem too, and I not understand what should I do to solve this problem, can you help me, here are my options when running the ‘clang’ scheme in the LLVM.xcodeproj:

-mmacosx-version-min=10.5  -emit-llvm -S -g -mllvm -sub -mllvm -sub_loop=-3 -mllvm -fla -mllvm -bcf -mllvm -debug -mllvm -bcf_loop=-3 -fno-experimental-new-pass-manager /Users/lee/Desktop/xx/S/obfuscator/obfuscator/ollvmtests/main.c -o /Users/lee/Desktop/xx/S/obfuscator/obfuscator/ollvmtests/main.ll

here is the output after use -###:

/Users/lee/Desktop/xxxx/S/obfuscator/obfuscator/build/Debug/bin/clang -cc1 -triple x86_64-apple-macosx10.5.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -emit-llvm -disable-free -main-file-name main.c -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 762 -dwarf-column-info -debug-info-kind=standalone -dwarf-version=2 -debugger-tuning=lldb -coverage-notes-file /Users/lee/Desktop/xxxx/S/obfuscator/obfuscator/ollvmtests/main.gcno -resource-dir /Users/lee/Desktop/xxxx/S/obfuscator/obfuscator/build/Debug/bin/…/lib/clang/4.0.1 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -fdebug-compilation-dir /Users/lee/Desktop/xxxx/S/obfuscator/obfuscator/build/Debug/bin -ferror-limit 19 -fmessage-length 0 -stack-protector 1 -fblocks -fblocks-runtime-optional -fno-experimental-new-pass-manager -fobjc-runtime=macosx-10.5.0 -fobjc-dispatch-method=non-legacy -fencode-extended-block-signature -fmax-type-align=16 -fdiagnostics-show-option -mllvm -sub -mllvm -sub_loop=-3 -mllvm -fla -mllvm -bcf -mllvm -debug -mllvm -bcf_loop=-3 -o /Users/lee/Desktop/xxxx/S/obfuscator/obfuscator/ollvmtests/main.ll -x c /Users/lee/Desktop/xxxx/S/obfuscator/obfuscator/ollvmtests/main.c

what should I do next step?