6 ms·
If you compile without debug symbols you don't get a trace after a seg fault. If you're taking first year programming and they give you a compiler incantation
by neutronicus 7y ago
If you compile without debug symbols you don't get a trace after a seg fault.
If you're taking first year programming and they give you a compiler incantation that doesn't include -g that will be your experience.
- saagarjha 7y agoThat's just a poor default, I guess. Rust compiles debug builds unless you tell it not to.
- neutronicus 7y agoThis may have changed since the days of my youth
- umanwizard 7y agoWhether 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.
- saagarjha 7y agoDon't you need to add [profile.release] debug = true to make this work?
- umanwizard 7y agoOh, you may be right. My company's main codebase does indeed have that; I had assumed it was the default.
- Freaky 7y agoI 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.
- steveklabnik 7y agoIIRC this is correct, libstd is built in release mode but with debuginfo.
- ComputerGuru 7y agoC/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).
- umanwizard 7y agoC/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 ()
- wahern 7y agoTry with -O3. 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.
- jcelerier 7y ago> If you compile without debug symbols you don't get a trace after a seg fault. uh... no. given volatile char* foo = 0x0; struct crasher { void crash() { *foo = 1; } }; int main() { crasher c; c.crash(); } and $ g++ foo.cpp $ ./a.out then $ coredumpctl gdb gives me (gdb) bt #0 0x000055cea1ff6187 in crasher::crash() () #1 0x000055cea1ff615c in main () The only case when you wouldn't get function names is if your binary has been stripped manually (or as part of a build system step)
- turndown 7y agoAs they are specifically talking about new programmers, using gdb in your example effectively communicates and confirms their point.
- saagarjha 7y agoGDB is not an advanced tool.
- aspaceman 7y agoThe whole point of this entire discussion was that it's an additional tool where beginners are used to the runtime spitting out a backtrace for them.
- pjmlp 7y agoBeginners should be using a friendly IDE to start with.
- viraptor 7y agoThat'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.