Let me start by saying that I've scoured other questions on here that are incredibly closely related, but haven't lent themselves to resolving my issue.
Setup:
svn co...
)I am new to using Eclipse/CDT, but familiar with GDB. When I try to debug an application that uses STL, upon the first occurrence of an STL object, I get the below error(s). On programs with many, many STL objects, I get so many errors, that it makes single-stepping impossible. I have here a small sample program for illustration purposes.
Here is my sample program:
#include <iostream>
using namespace std;
int main() {
string sComplex;
sComplex = "!!!Hello World!!!";
cout << sComplex << endl; // prints !!!Hello World!!!
//cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
cout << "This is a new string that writes out a numeric..." << endl;
int i = 1000;
cout << "Value for integer 'i' is : '" << i << "'." << endl;
cout << " In HEX: '";
cout << std::hex << std::showbase << i;
cout << "'." <<endl;
return 0;
}
Here are the errors that print out as soon as it hits the first line (STL string instantiation):
Traceback (most recent call last): File "/usr/lib64/../share/gdb/python/libstdcxx/v6/printers.py", line 558, in to_string return self.val['_M_dataplus']['_M_p'].lazy_string (length = len) RuntimeError: Cannot access memory at address 0xffffffffffffffe8
Traceback (most recent call last): File "/usr/lib64/../share/gdb/python/libstdcxx/v6/printers.py", line 558, in to_string return self.val['_M_dataplus']['_M_p'].lazy_string (length = len) RuntimeError: Cannot access memory at address 0xffffffffffffffe8
Traceback (most recent call last): File "/usr/lib64/../share/gdb/python/libstdcxx/v6/printers.py", line 558, in to_string return self.val['_M_dataplus']['_M_p'].lazy_string (length = len) RuntimeError: Cannot access memory at address 0xffffffffffffffe8
First, notice that there are 3 separate errors for this one object. I have verified that the python pretty print module is installed and I have tried suggestions to limit the length in to_string, but to no avail. If I step past the string instantiation, everything works fine and I can see the simple string value of the variable. Mouse-over looks good too. When I debug this same application using gdb straight on the command-line, I don't see any such errors and variable values print pretty.
(gdb) p sComplex
$1 = "!!!Hello World!!!"
(gdb) p sComplex.c_str()
$2 = 0x602028 "!!!Hello World!!!"
I've tried various suggestions with my .gdbinit file and Eclipse's Window->Preferences->C/C++->Debug->GDB settings, even disabling pretty print, but it still happens. I don't know what else to try next.
I finally decided to revisit this issue and finally resolved it by following solutions similar to this one, and by additional editing of my custom printers.py. Hopefully this helps someone else who's hit this.
svn co svn://gcc.gnu.org/svn/gcc/trunk/libstdc++-v3/python
) to $HOME/gdb/gdb_printers/
.
/usr/share/gdb/
).
You should have a directory structure like this when you're done:This structure has to be EXACT or it won't use your printers.py down in /v6/.
Edit printers.py, specifically StdStringPrinter::to_string
as follows (adding try/except/else):
def to_string(self):
# Make sure &string works, too.
type = self.val.type
if type.code == gdb.TYPE_CODE_REF:
type = type.target ()
# Calculate the length of the string so that to_string returns
# the string according to length, not according to first null
# encountered.
# I wrapped this section in a try/except/else block so that uninitialized
# strings don't cause massive RuntimeError exception reporting during debugging
# with or without pretty printers enabled. -jkw
try:
ptr = self.val ['_M_dataplus']['_M_p']
realtype = type.unqualified ().strip_typedefs ()
reptype = gdb.lookup_type (str (realtype) + '::_Rep').pointer ()
header = ptr.cast(reptype) - 1
len = header.dereference ()['_M_length']
except RuntimeError:
#print 'Caught exception'
return ''
else:
return self.val['_M_dataplus']['_M_p'].lazy_string (length = len)
Create/edit $HOME/gdb/.gdbinit
file and put the following in it. Note the path must match the path to the 'python' directory in the above image/tree view.
python
import sys
sys.path.insert(0, '/home/(user_id)/gdb/gdb_printers/python')
from libstdcxx.v6.printers import register_libstdcxx_printers
register_libstdcxx_printers (None)
end
In Eclipse, under Window -> preferences -> C/C++ -> Debug -> GDB
, set the path to gdb
and your .gdbinit
file. You may also need to set this on any existing debug configurations that you want to use your printers.py.
GDB debugger: /usr/bin/gdb
GDB command file: /home/(user_id)/gdb/.gdbinit
From there, debugging functions just as you think it should.