RE: GDB 8.0 release/branching 2017-03-20 update

Wiederhake, Tim
2017-04-06T14:40:51Z

Hi all,

> Tim, are you OK with the result of this discussion, as well?

I'm back and have read the mails you all wrote about this topic. Let me
summarize to make sure I understand everything correctly.

The Python interface shall look like this (from Python's perspective):

gdb:
Record start_recording([str method], [str format])
Record current_recording()
None stop_recording()

Unchanged.

gdb.Record:
str method
str format
RecordInstruction begin
RecordInstruction end
RecordInstruction replay_position
RecordInstruction[] instruction_history
RecordFunctionSegment[] function_call_history
None goto(RecordInstruction insn)

gdb.Record loses the "ptid" attribute. "instruction_history" and
"function_call_history" actually returns a "list" or "list-like object"
as there is no way to enforce the type of elements in this list on a
language level in Python. Practically, these list will always contain
"RecordInstruction" / "RecordFunctionSegment" objects since we control
their creation. "*_history" may return "None" if the current recording
method cannot provide such a list.

gdb.Instruction:
int pc
buffer data
str decode
int size

gdb.Instruction is meant to be an abstract base class. The user will
never receive a raw gdb.Instruction object and accessing any attribute
in this class will throw a "NotImplementedError" (from what I
understand, that's the preferred way to handle this kind of situation
in Python).

gdb.RecordInstruction (gdb.Instruction):
int pc <inherited from gdb.Instruction>
buffer data <inherited from gdb.Instruction>
str decode <inherited from gdb.Instruction>
int size <inherited from gdb.Instruction>
int error
gdb.Symtab_and_line sal
bool is_speculative

gdb.RecordInstruction is a sub class of gdb.Instruction. It loses
the "number" attribute. "error" will be "None" if there is no error.

gdb.<Whatever>Instruction (gdb.Instruction):
int pc <inherited from gdb.Instruction>
buffer data <inherited from gdb.Instruction>
str decode <inherited from gdb.Instruction>
int size <inherited from gdb.Instruction>
...

Created by other Python interfaces, e.g. a function that dissasembles
target memory.

gdb.RecordFunctionSegment:
gdb.Symbol symbol
int level
gdb.RecordInstruction[] instructions
gdb.RecordFunctionSegment up
gdb.RecordFunctionSegment prev
gdb.RecordFunctionSegment next

Renamed from "gdb.BtraceFunctionCall" to better fit the general scheme.
Loses the "number" attribute. As above, "instructions" actually returns
a list / list-like object. "prev_sibling" and "next_sibling" are
renamed to "prev" and "next" for simplicity (discussed with Markus
off-list).

Correct so far?

Initially I supported the idea of losing the "number" attributes in
"gdb.RecordInstruction" and "gdb.RecordFunctionSegment", but I see a
problem with that now: If an instruction is executed multiple times (e.g. in a
loop), all user visible attributes for these gdb.RecordInstruction objects are
the same, nevertheless a comparison with "==" does not yield "True" because they
represent, well, two different instances of execution of that instruction.
Keeping the "number" attribute in would show the user, why those objects are not
equal. Therefore I propose to retain the "number" attribute in
"gdb.RecordInstruction" and for symmetry in "gdb.RecordFunctionSegment" as well.

Markus and I further discussed how we handle gaps or other errors in the trace
from the Python point of view. We came to the conclusion that it would be
beneficial for the user if we replaced the definition of "gdb.RecordInstruction"
above with the following two:

gdb.RecordInstruction (gdb.Instruction):
int pc <inherited from gdb.Instruction>
buffer data <inherited from gdb.Instruction>
str decode <inherited from gdb.Instruction>
int size <inherited from gdb.Instruction>
int number
gdb.Symtab_and_line sal
bool is_speculative

gdb.RecordGap:
int number
str error_message
int error_code

Does NOT inherit from gdb.Instruction.

gdb.Record.instruction_history would then not "return a list of
RecordInstructions" but instead "return a list of RecordInstructions and
(potentially) RecordGaps".

The user needs to distinguish between instructions and gaps somehow anyway, and
this solution would let them do so quite nicely. Example code:

r = gdb.current_recording()
for insn in r.instruction_history:
try:
print insn.pc, insn.sal
except:
# It's a gap!
print insn.error_message

Please let me know if you agree with this so I can get to work as soon as
possible.

Regards,
Tim

> -----Original Message-----
> From: Joel Brobecker [mailto:brobecker@adacore.com]
> Sent: Friday, March 31, 2017 6:03 PM
> To: Metzger, Markus T <markus.t.metzger@intel.com>
> Cc: Yao Qi <qiyaoltc@gmail.com>; Wiederhake, Tim
> <tim.wiederhake@intel.com>; gdb-patches@sourceware.org;
> xdje42@gmail.com
> Subject: Re: GDB 8.0 release/branching 2017-03-20 update
>
> > Tim, are you OK with the result of this discussion, as well?
> >
> > Joel, do we have a week or so for Tim to send a patch?
>
> We do (I am going to be away all of next week). After that, let's cut the
> branch no matter what, and backport if necessary.
> I'd like to start soon, so as to give time for stabilization if needed.
>
> --
> Joel
Intel Deutschland GmbH
Registered Address: Am Campeon 10-12, 85579 Neubiberg, Germany
Tel: +49 89 99 8853-0, www.intel.de
Managing Directors: Christin Eisenschmid, Christian Lamprechter
Chairperson of the Supervisory Board: Nicole Lau
Registered Office: Munich
Commercial Register: Amtsgericht Muenchen HRB 186928