Re: Crashing gdb with python-prettyprinting

Joachim Protze
2010-08-09T12:19:13Z

Am 30.07.2010 21:12, schrieb Tom Tromey:
> If there is code in the python layer that gets this wrong, please let us
> know about it, that would definitely be a bug.
>
> Joachim> Is it right, that the content of frame_info should not change
> Joachim> while the program is halted and i just call a series of "info
> Joachim> locals"?
>
> Aha. If a pretty-printer causes the frame cache to be invalidated, then
> the frame_info passed to print_frame_local_vars will be no good. That
> may be what you are seeing. You could verify this by putting a
> breakpoint on reinit_frame_cache and then doing "info locals". If it
> triggers, that is bad.

I did this and found the point where it crashed - i did not remember,
that i use a parse_and_eval-call for each generation of an pp-object.
Now i was able to write a condensed version of my problem (see appendix)

In my own code, i have an object for each variable, that should be
printed. It caches the information, but i have to use a call to a
programm-function in each init. For more complex data structures this
also crashed on first call of "info locals".
To reproduce my failure just run the code below, set breakpoint to
return of main, load the python-script and "info local" till segfault

> Joachim> I'm new in debuging gdb by gdb. Can someone give me a hint, how
> Joachim> i can set a breakpoint in the outer gdb while the inner gdb is
> Joachim> running?
>
> What I do is use C-c to go back to the top gdb, then set my breakpoints,
> then "cont" to resume the inner gdb.

Thanks for this hint - i did not recognize that the outer gdb will catch
the C-c signal, but thought i would interrupt the execution of the inner
program

Thanks and best regards

Joachim

----------------- pptest.c -----------------
enum test_enum{
zero,
one,
two,
three,
four,
five,
};

typedef int testint;

enum test_enum get_test_enum(int i){
return (enum test_enum)i;
}

int main(int argc, char* argv[]){

testint a, b, c, d, e, f;
testint arr[]={0,1,2,3,4,5};

a=0;
b=1;
c=2;
d=3;
e=4;
f=5;

return 0;
}

----------------- pptest.py -----------------
import gdb
import re

class pp_test:
"""testprinter with code interaction"""
def __init__(self, id):
self.id = id
def to_string(self):
return str(gdb.parse_and_eval("get_test_enum(%i)" % self.id))

def lookup_function (val):
'''Look-up and return a pretty-printer that can print val.'''
type = val.type;
# If it points to a reference, get the reference.
if type.code == gdb.TYPE_CODE_REF:
type = type.target ()
typename = str(type_from_value(type))
for function in pp_dict:
if function.search (typename):
result = pp_dict[function] (val)
return result
return None

pp_dict = {}
pp_dict[re.compile('^testint$')] = lambda val: pp_test(val)
gdb.pretty_printers = []
gdb.pretty_printers.append (lookup_function)