GDB C++ Not possible to get source core line when error (Segmentation Fault)

-1

I have couple of days dealing with a Segmentation Fault error and I'm not capable to found it. I'm using gdb to debug it but GDB is not giving me any details fo the line where error is happening.

Now, I am generating a error just to ensure my build is compatible with GDB. I'm compiling using cmake with degub enabled: cmake -DCMAKE_BUILD_TYPE=Debug .. and I also ensured -g flag is enables in CMakeFiles/SmartGate.dir/flags.make and I manually added -ggdb flag.

I used make VERBOSE=1 SmartGate to ensure flags are present in compilation and linking process and they are.

I'm able to load my build in gdb:

GNU gdb (GDB) 10.1
Copyright (C) 2020 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "armv7l-unknown-linux-gnueabihf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb) file  SmartGate
Reading symbols from SmartGate...

And I also capable to show SourceCode where injeted error is present:

(gdb) l SmartGate.cpp:30
25      sqlite3 *db;
26  
27      std::string tmp_db = NULL;//"controller_test_data.db";
28      int rc = sqlite3_open(tmp_db.c_str(), &db);
29      if (rc)
30      {
31          spdlog::error("Can't open database: ", sqlite3_errmsg(db));
32          sqlite3_close(db);
33          exit(1);
34      }
(gdb) 

But when error happened, I only get the following backtrace:

(gdb) r
Starting program: /home/pi/SmartGate/build/SmartGate 
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/arm-linux-gnueabihf/libthread_db.so.1".
[New Thread 0xab33a1e0 (LWP 12870)]
[New Thread 0xaa2591e0 (LWP 12871)]
terminate called after throwing an instance of 'std::logic_error'
  what():  basic_string::_M_construct null not valid

Thread 1 "SmartGate" received signal SIGABRT, Aborted.
0xb3e3ef24 in raise () from /lib/arm-linux-gnueabihf/libc.so.6
(gdb) bt
#0  0xb3e3ef24 in raise () from /lib/arm-linux-gnueabihf/libc.so.6
#1  0xb3e2a230 in abort () from /lib/arm-linux-gnueabihf/libc.so.6
#2  0x00000000 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

This is the error output for the actual error I want to trace:

Thread 1 "SmartGate" received signal SIGSEGV, Segmentation fault.
0xb6fb9c1c in memcpy () from /usr/lib/arm-linux-gnueabihf/libarmmem-v7l.so
(gdb) bt
#0  0xb6fb9c1c in memcpy () from /usr/lib/arm-linux-gnueabihf/libarmmem-v7l.so
#1  0x00000000 in ?? ()
Backtrace stopped: previous frame identical to this frame (corrupt stack?)

Any advice?

c++
linux
gcc
gdb
asked on Stack Overflow Jan 15, 2021 by Miguel Resendiz • edited Jan 17, 2021 by Miguel Resendiz

1 Answer

-2

Your question is about unwinding from segmentation fault, but your example about unwinding from abort(). These are completely separate things (in other words, the answer to the question about your contrived example is unlikely to help with your actual problem).

terminate called after throwing an instance of 'std::logic_error' what(): basic_string::_M_construct null not valid
I only get the following backtrace:

What's happening here:

  1. Your code calls equivalent of std::string foo(nullptr);
  2. std::string constructor detects this bug in your program and throws exception
  3. Since you don't have a catch block, std::terminate() is called, which
  4. eventually calls abort()
  5. GDB is having trouble unwinding the stack to the point where abort() was called.

There are several ways you can avoid the need to unwind stack from abort().

  1. Audit places in your program which construct new std::string instances, make sure none of them pass nullptr as an argument.
  2. Set breakpoint on std::string::string(const char *s) constructor. Make it conditional on s == NULL.
  3. Ask GDB to stop when exception is thrown with catch throw command. Documentation.
  4. You can rebuild your libc.so.6 with debug info, or install libc6-dbg or similar package from your distribution. This might help GDB to unwind from abort().
answered on Stack Overflow Jan 16, 2021 by Employed Russian • edited Jan 16, 2021 by Employed Russian

User contributions licensed under CC BY-SA 3.0