I want to debug a c++ code using the generated executable with bazel, but for some reason, the bazel don't build the code on x64 architecture or the executable does not work on debug mode.
My files are
main.cpp
#include <iostream>
int main()
{
int a = 3;
int b = 5;
int c = a + b;
/* code */
std::cout << "Hello world" << std::endl;
return 0;
}
I use this command to build my app
bazel build //src/app:main --strip=never --compilation_mode=dbg
but when I try to debug the app after I set breakpoints I get this error in the console
for example, if I run
gdb main.exe
then
(gdb) break main
I get
No symbol table is loaded.
Question how to load the symbols inside the main.exe when I build the code using the bazel build command??
Bazel on Windows builds C++ code using MSVC by default. I reckon the debugging data format used by GCC is different from MSVC's .pdb files, which would explain why you can't use gdb
to debug the Bazel-built binary.
To build with MingW GCC instead of the default MSVC, you must tell Bazel to use that compiler:
bazel build -c dbg --compiler=mingw-gcc //src/app:main
Here's more info about this --compiler
flag value [1].
This failed for me first, so I followed instructions of https://stackoverflow.com/a/30071634/7778502 and installed mingw-w64-x86_64-gcc
.
Now I could build //src/app:main
with Bazel, and use gdb
to set a breakpoint:
$ gdb /c/src/so53840959/CPP_TESTS/project/bazel-bin/main/app.exe
GNU gdb (GDB) 7.11.1
...
Traceback (most recent call last):
File "<string>", line 3, in <module>
ImportError: No module named libstdcxx.v6.printers
/etc/gdbinit:6: Error in sourced command file:
Error while executing Python code.
Reading symbols from /c/src/so53840959/CPP_TESTS/project/bazel-bin/main/app.exe...done.
(gdb) break main
Breakpoint 1 at 0x401568
(gdb)
I'm not familiar with gdb
but the Error looks benign and everything looks OK.
[1] To find this --compiler
flag value, I looked at the registered C++ toolchains. I'm not aware of a user-friendly way to do this (and I don't want to go into details about toolchains here) but all we need to know is this:
Run bazel query @local_config_cc//:toolchain --output=build
.
This will print the C++ toolchains rule's definition, which is an auto-generated build rule that tells Bazel what C++ toolchains it can use.
Look at the line starting with toolchains = {...
.
It is a dictionary where each key defines a --cpu
flag value, or a --cpu
and --compiler
flag value pair. Without going into details about syntax here, you can probably see an entry with key x64_windows|mingw-gcc
, meaning you can build with --cpu=x64_windows
and --compiler=mingw-gcc
. (Since --cpu=x64_windows
is the default on Windows, you can leave it out.)