Dave Malcolm <dmalc...@redhat.com> added the comment:

See https://bugzilla.redhat.com/show_bug.cgi?id=556975#c21

I'll try to summarize: as I understand things, the issue is that on 64-bit gcc 
builds with enough optimization, the argument "PyFrameObject *f" is passed as a 
register, and that gets clobbered at various locations within the 
implementation of PyEval_EvalFrameEx.

The DWARF debug data contains a mapping between ranges of program counter 
values and methods for calculating the values of variables, and in many 
locations within PyEval_EvalFrameEx, it doesn't have enough information to 
figure out what the value of "f" is.

It works on i386: the calling conventions are different, and it's fairly easy 
for gdb to walk up the stack and find "f".

I believe my RH colleagues who hack on gcc and gdb are working on improving 
this so that DWARF can handle such cases (where "f" doesn't change during the 
function call), but Jakub describes that as "at least a year from now"

In the meantime there are some options.

(i) A dirty hack is that in some places in the function on x86_64 I've seen 
that the value of "f" is stored in the $rbp register.  We could use something 
like this as a fallback for when directly querying gdb for "f" fails:
  _type_PyFrameObjectPtr = gdb.lookup_type('PyFrameObject').pointer()
  f = gdb.parse_and_eval('$rbp').cast(_type_PyFrameObjectPtr)
and then see if the value looks sane (e.g. does it have a meaningful ob_type?  
does 0 ==strcmp($rbp->ob_type->tp_name, "frame"); if so, then that's probably 
the value of "f", and use it.

Obviously that would be highly fragile; it may be something I'm seeing on my 
particular version of gcc, but might not work for other people's gcc.  Also I 
suspect that it will give misleading results when traversing the stack of 
C-level frames.

Another approach would be to simply accept that it isn't going to work on 
x86_64 with gcc with optimizations turned on until a later version of gcc.

We could handle this:
(ii) by trying to detect this situation during test_gdb.py, and to skip the 
affected tests.
(iii) by generalizing the tests so that they can handle the case where 
arbitrary frames aren't readable.

Approach (iii) seems most promising to me, and I'll try to cook up a patch 
(though I want to try approach (i), as it would be nice to get visibility into 
these frames)

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<http://bugs.python.org/issue8482>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to