This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
Hello, We have noticed that GDB skips too much prologue when inserting a breakpoint on a given function. I will provide the source code below, but it's not very important to understand the cause of the problem. Here is an extract: 12 procedure print is 13 A : Integer; 14 begin 15 A := I; 16 null; 17 end print; Right now, when we insert a breakpoint on function ``print'' (which encoded name is ``generics__test_generics__other_instance__print.0''), we end up placing the breakpoint at line 17, but the expected location was at line 15: (gdb) b "generics__test_generics__other_instance__print.0" Breakpoint 1 at 0x100112e0: file generics.adb, line 17. A quick look at the assembly code for function ``print'' shows what causes skip_prologue() to go too far: Line 12: <print.0+0>: stw r31,-4(r1) <print.0+4>: stwu r1,-48(r1) <print.0+8>: mr r31,r1 <print.0+12>: stw r11,24(r31) Line 15: <print.0+16>: li r0,12 <print.0+20>: stw r0,28(r31) Line 17: <print.0+24>: lwz r1,0(r1) <print.0+28>: lwz r31,-4(r1) <print.0+32>: blr The first problem is with the insn at +16 (li [...]). If part of the prologue, this instruction should be part of a pair of instructions saving vector registers. This is not the case here. However, skip_prologue() doesn't check that, and instead considers by default that this insn is part of the prologue (ie "prev_insn_was_prologue_insn" remains set to 1). So the first change I made was to *not* consider this instruction as part of the prologue unless the next one is part of the prologue. Normally, you would rather check that the next instruction is even one of the instructions that come as a pair with that "li" instruction. But this is not necessary in our case, because we're not trying to tag each instruction individually, we're trying to find the upper bound of the prologue. So long as some later instruction is recognized as part of the prologue (whether it be part of that instruction pair or not), we need to update our upper bound accordingly. On the contrary, if none of the following instructions we scan belong to the prologue, then we should not include that instruction in the function prologue. Hence my first change (I hope I was clear enough?). The second problem is with the following instruction: "stw r0,28(r31)". The prologue analyzer tags this instruction as being part of the prologue, but this is incorrect, I believe. According to the PPC ABI document I have, only r3 to r10 are used for parameter passing: For PowerPC, up to eight words are passed in general purpose registers, loaded sequentially into general purpose registers r3 through r10. Unfortunately, skip_prologue() detects the "stw Rx, NUM(R31)" sequence, but forgot to check the register number. Here, it's the scratch register zero, so the instruction should not be considered part of the prologue either. The same applies to instructions involving saving floating point arguments passed via registers: Only f2 to f8 are used for that purpose. So my second change was to create a new function extracted from skip_prologue() named store_parameter_on_stack_prologue_insn_p(), and then improve it to also check for register numbers. 2004-04-02 Joel Brobecker <brobecker@gnat.com> * rs6000-tdep.c (store_parameter_on_stack_prologue_insn_p): New function, an improved version of some code extracted from skip_prologue(). (skip_prologue): Use store_parameter_on_stack_prologue_insn_p() to detect instructions saving a parameter on the stack. Do not mark "li rx, SIMM" instructions as part of the prologue, unless the following instruction is also part of the prologue. Tested on ppc-aix-5.1. This fixes several FAILs and XFAILs as well as our problem: In gdb.base: condbreak.exp: run until breakpoint at marker1 XFAIL PASS condbreak.exp: run until breakpoint at marker2 XFAIL PASS ena-dis-br.exp: continue to auto-disabled break marker2 XFAIL PASS ena-dis-br.exp: continue to break marker1 XFAIL PASS ena-dis-br.exp: continue to break marker1, 2nd time XFAIL PASS funcargs.exp: continue to call5b FAIL PASS funcargs.exp: print *stp FAIL PASS funcargs.exp: print st FAIL PASS funcargs.exp: print un FAIL PASS funcargs.exp: run to call5a FAIL PASS I also get some improved results in gdb.threads, and it seems related to breakpointing, but I am always cautious with varying results in that part of the testsuite, and I haven't had time to study them. OK to apply? Thanks, -- Joel Here is the entire Ada code we used to reproduce the problem. To build them, place the sources in a file, say sources.ada, and then do: % gnatchop sources.ada % gnatmake -g generics_main << package body Generics is procedure Test_Generics is package other_instance is new the_generic(12); begin other_instance.print; null; end Test_Generics; package body the_generic is procedure print is A : Integer; begin A := I; null; end print; end the_generic; end Generics; package Generics is generic i : integer; package the_generic is procedure print; end the_generic; procedure Test_Generics; end Generics; with generics; procedure generics_main is begin generics.test_generics; end generics_main; >>
Attachment:
rs6000-tdep.c.diff
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |