Gdb printing std::map elements - c++

I have a std::map data member inside a class called ExecState:
class ExecState { // ...
std::map<int,ref<Expr> > ab_size;
// ...
};
When I print it from gdb I see the expected values:
(gdb) print state.ab_size
$1 = std::map with 1 elements = {[1] = {ptr = 0x2a221d0}}
However, when I try to access the element itself, gdb fails:
(gdb) print state.ab_size[1]
Attempt to take address of value not located in memory.
What am I doing wrong here? thanks!

When I print it from gdb I see the expected values:
You see this because of the magic of pretty-printers. To see the actual contents of the variable, try print/r state.ab_size.
However, when I try to access the element itself, gdb fails:
GDB didn't fail, but the pretty printers aren't magical enough to grant your wish. You'll have to "fish out" the value by using the actual data elements, not the illusion that pretty printers create (and this is hard).

Related

GDB define command: print $arg1 doesn't print the correct value when in define

I want to define a new command which basically sets a breakpoint on a line, print a value of a certain variable and then continues execution. Unfortunately I am having issues. Here is the code I am using
(gdb) define print_and_continue
Type commands for definition of "print_and_continue".
End with a line saying just "end".
>break $arg0
>command $bpnum
>print $arg1
>continue
>end
>end
So I want to print the value of variable len which is defined in linked_list.h:109. And I execute the following code:
(gdb) print_and_continue linked_list.h:111 len
Breakpoint 1 at 0x388a: linked_list.h:111. (12 locations)
(gdb) r
...
Breakpoint 1, linked_list<test_struct<1>, 1>::remove_if<run_test<1, 1, 1>(std::vector<int, std::allocator<int> >&)::{lambda(test_struct<1> const&)#1}>(run_test<1, 1, 1>(std::vector<int, std::allocator<int> >&)::{lambda(test_struct<1> const&)#1}&&) (this=0x7fffffffdca0, condition=...) at linked_list.h:112
112 linked_list_node* prev = nullptr;
$1 = void
It seems like $arg1 in print function didn't get replaces by the actual argument. What am I doing wrong?
It seems like $arg1 in print function didn't get replaces by the actual argument.
I don't believe that's what is actually happening. Rather, everything following command $bpnum is attached to the newly-created breakpoint literally (without any expansion at all). You can see that happening with info break, which will show something like:
Num Type Disp Enb Address What
1 breakpoint keep y 0x0000000000001136 at ...
print $arg1
continue
This is generally what you would want (deferring evaluating the argument until the time breakpoint is hit). Otherwise you would print current value of len if you use print len, when what you want is to print the value of len when the breakpoint is hit.
Of course, when the breakpoint is hit, there is no $arg1 (or $arg0) anywhere around, so you get the same output you'd get trying to print any other non-existent GDB variable.
What am I doing wrong?
You are using "quick hack of a language" (which is what the "native" GDB scripting language is), instead of using a proper programming language.
I am 99.99% certain that defining print_and_continue is possible (and probably quite easy) using embedded Python.
That said, I don't believe that print_and_continue is all that useful (in my 20+ years of using GDB, I never needed anything like that).

Make GDB print context around every time

LLDB print context around current line every time like this:
int a = 12;
int b = a * 13;
-> printf("%d\n", b);
return 0;
}
In the same time, GDB just print one current line:
-> printf("%d\n", b);
Can I make GDB print context every step like LLDB? Googling give all around list command.
a way to accomplish this might be by defining a macro that redefines a keyword, such as 's' or 'n'.
for example, if you wanted to print out the value of the stack pointer at each step you could redefine 's' by entering these lines into the (gbd) console:
def s
step
info registers sp
end
now every time you use the command 's' you actually do a step and print of the sp register
There is no built-in way to do this.
You could maybe make it work, sort of, using hookpost-stop to invoke an explicit list command.
I think most people just use one of the many gdb GUIs instead, though.

Boost Shared Memory Map reattach

My Issue is the following:
Why can my program not re-attach to the shared memory map?
I do the following in my program(it might be easier to use the example from the boost page for you while this is only a small fragment from my program):
First time, initialize it:
m_sharedMemory = new managed_shared_memory(create_only, segmentName.c_str() , 1000000);
m_hashMap = m_sharedMemory->construct<MyHashMap>(segmentName.c_str())( 3, boost::hash<std::string>(), std::equal_to<std::string>() , m_sharedMemory->get_allocator<ValueType>());
Second time "Re-Attach"
m_sharedMemory = new managed_shared_memory(open_only, segmentName.c_str());
m_hashMap = m_sharedMemory->find<MyHashMap>(segmentName.c_str()).first;
My Issue here is ,if 2 items get inserted the .second call on the returned object from find will show "1" which is actually wrong, its supposed to show 2, after this if my program tries to find anything in the stored map the program crashes. Has somebody been doing this already.
If i do the same thing in the initial program run it is no problem to lookup values from the hash. This only occurs if the program was initialized and later the program is restarted and does the attach and tries to retrieve values formerly inserted.
Thanks for the help.
Boost Quick Ref Map Example
While i was talking to the "maker" of this library he told me that it will only be possible to use the map within the same process.

Cannot access STL C++ container values with GDB

I am debugging C++ code and I have problems when trying to access to an std::list.
The problem is that I cannot get the address associated to the head node ($3 refers to the list):
p $3._M_impl._M_node
$21 = {
_M_next = 0x240ee70,
_M_prev = 0x240ee70
}
I get the following error message when I try to get the head node address:
(gdb) p &($3._M_impl._M_node)
Attempt to take address of value not located in memory.
I also have tried with the STL extension available from the Internet and it also fails at the same point.
set $head = &$arg0._M_impl._M_node
I have looked at Google an this is all I can find about the problem:
http://permalink.gmane.org/gmane.comp.gdb.devel/9496
But it doesn't solve my problem. Any suggestions are more than welcomed.
Thanks in advance

Sporadic segfault in c++ python extension

I have a python object which accesses and downloads some text via HTTP.
I'm running this python object, and processing that text, using a c++ code.
I.e.
/* CPPCode.cxx */
int main(...) {
for(int i = 0; i < numURLs; i++) {
// Python method returns a string
PyObject *pyValue = PyObject_CallMethod(pyObjectInstance, pyFunctionName, par1, par2....);
string valString = PyString_AsString(pHistValue);
// ... process string ...
}
}
/* PyObject.py */
class PyClass:
def PyFunction(...):
try: urlSock = urllib.urlopen(urlName)
except ...
while(...) :
dataStr = urlSock.readline()
# do some basic string processing....
return dataStr
Most URLs work fine---the c++ code gets the proper string, I can process it, all is happy and well. A few particular URLs which look (basically) the same as the others on a browser, lead to a segfault in the PyString_AsString() method:
Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0x00000000000000b2
0x000000010007716d in PyString_AsString ()
If I print out the string that should be returned by the python method ('dataStr' in the pseudo-code above), it looks fine! I have no idea what could be causing this problem---any tips on how to procede would be appreciated!
Thanks
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
SOLUTION:
The template code I was using had a call to
Py_DECREF(pyValue)
before I called
PyString_AsString(pyValue)
Why it was being deallocated for certain particular function calls, I have no idea. As 'Gecco' says in the comments below,
'PyString_AsString documentation says: "The pointer refers to the internal buffer of string, not a copy. The data must not be modified in any way, unless the string was just created using PyString_FromStringAndSize(NULL, size). It must not be deallocated." '
PyString_AsString documentation says: "The pointer refers to the internal buffer of string, not a copy. The data must not be modified in any way, unless the string was just created using PyString_FromStringAndSize(NULL, size). It must not be deallocated."
Please ensure you do not deallocate this buffer
If you compile your C code with the -g debug flag (in GCC at least) then you can run your python code using the gnu debugger gdb:
$ gdb /path/to/python/compiled/against
... blah ...
(gdb) run PyObject.py
and you should catch your segfault.
My guess is the Py_DECREF is somehow getting a NULL value.