C/C++ programs will normally have function names in backtraces, just not line numbers.
$ cat test.c
int g() {
int *p = 0;
*p = 5;
}
int f() {
g();
}
int main() {
f();
}
$ cc test.c
$ ./a.out
[1] 3377 segmentation fault (core dumped) ./a.out
$ gdb -q a.out core
Reading symbols from a.out...
(No debugging symbols found in a.out)
[New LWP 3377]
Core was generated by `./a.out'.
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x0000557379b7613d in g ()
(gdb) bt
#0 0x0000557379b7613d in g ()
#1 0x0000557379b76158 in f ()
#2 0x0000557379b7616d in main ()
Another wrinkle is that the symbol names of extern functions need to be in the binary regardless of debug level, though the main binary is a special case, unlike shared libraries. So you'll get different results again if you add -fPIC -rdynamic (or possibly just -fPIC) to -O3, similar results as-if you compiled a library with -O3 -fPIC -shared. But then if you define f and g as statically scoped -fPIC -rdynamic won't change the behavior.
It follows that there's a potential conflict between code optimization and the ability to determine function names and line numbers for a trace. To preserve the ability to associate the programer counter (PC) to distinct function names and line numbers a compiler might need to abstain from completely inlining, merging, eliding, or otherwise optimizing some functions and code blocks (though that doesn't mean it needs to preserve actual function call behavior). People will endlessly debate the cost+benefit, but it's something to keep in mind for performance critical code blocks.
> As they are specifically talking about new programmers, using gdb in your example effectively communicates and confirms their point
New programmers would be using IDEs, press the green arrow "play" button and launch the app with the debugger enabled without them knowing, which would cause the editor to jump directly to where the issue is
I'm sorry but there are bad teachers / courses everywhere, that does not reflect on the technology (though C++ has it really bad for some reason). When I was in school learning how to debug was one of the first classes we had.
If they were teaching you rust be sure that they wouldn't have told you about cargo either.
That is a reflection of your school, and not the language.
I'm a self taught C/C++ programmer, learning and becoming comfortable with gdb was one of the first few things I taught myself after learning how to compile code into a binary back in the 1990's.
That's a naive view. Depends who's learning. Is C++ their 5th language and they know how to read resulting assembly? Is it their first experience at 10yo and they're struggling with what variables and types are? Anywhere in between?
Gdb beyond what the learning person can comfortably handle at the time and that's what matters.
Being able to use a debugger should be an essential part of any curriculum. GDB is only an advanced tool if you're an advanced user; it's useful for the entire spectrum of programming language users.
That everything is relative. That gdb absolutely is advanced and complicated dark magic if you’ve learned to code/debug on and been spoiled by an easy to use IDE.
C/C++ compile some weird default of neither debug nor optimized, basically the least helpful thing anyone could want (no performance optimizations, no debug symbols, and maybe-maybe-not asserts depending on if the standard library you’re using or the libraries you’re depending on used #if NDEBUG or #if DEBUG to gate the assertion checks. And not optimized for size either, if that’s what you were wondering).
Whether a build is debug or release is independent of whether it contains debug symbols. Both `cargo build` and `cargo build --release` produce builds with debug symbols.
I think you still get symbols for libstd without that. I can see why that would lead to confusion - stripping a plain --release build still saves a few MB.
what do you mean ? in which case don't you get a backtrace in C++ ?