* [CRIS] dwarf2 frame sniffer problem?
@ 2004-03-10 16:53 Orjan Friberg
2004-03-10 16:59 ` Daniel Jacobowitz
2004-03-19 0:09 ` Orjan Friberg
0 siblings, 2 replies; 36+ messages in thread
From: Orjan Friberg @ 2004-03-10 16:53 UTC (permalink / raw)
To: gdb-patches
After getting the CRIS port into shape without the dwarf2 frame sniffer,
I hooked it in and found that basic stuff like next over a function call
no longer works. (More specifically, after stepping into the function,
gdb sets the breakpoint on the jump instruction itself, rather than at
the instruction after.)
I do get a complaint "During symbol reading, Incomplete CFI data;
unspecified registers at 0x000802f6." already by the time I get to
main(), where 802f6 is the first address in main(), which is where the
subroutine pointer is pushed. Although there is a comment in
dwarf2-frame.c explaining the complaint, I'm not sure how seriously I
should take it.
Thanks for any idea on what might be the cause or where to start digging.
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-10 16:53 [CRIS] dwarf2 frame sniffer problem? Orjan Friberg
@ 2004-03-10 16:59 ` Daniel Jacobowitz
2004-03-19 0:09 ` Daniel Jacobowitz
2004-03-19 0:09 ` Orjan Friberg
2004-03-19 0:09 ` Orjan Friberg
1 sibling, 2 replies; 36+ messages in thread
From: Daniel Jacobowitz @ 2004-03-10 16:59 UTC (permalink / raw)
To: Orjan Friberg; +Cc: gdb-patches
On Wed, Mar 10, 2004 at 05:53:50PM +0100, Orjan Friberg wrote:
> After getting the CRIS port into shape without the dwarf2 frame sniffer,
> I hooked it in and found that basic stuff like next over a function call
> no longer works. (More specifically, after stepping into the function,
> gdb sets the breakpoint on the jump instruction itself, rather than at
> the instruction after.)
>
> I do get a complaint "During symbol reading, Incomplete CFI data;
> unspecified registers at 0x000802f6." already by the time I get to
> main(), where 802f6 is the first address in main(), which is where the
> subroutine pointer is pushed. Although there is a comment in
> dwarf2-frame.c explaining the complaint, I'm not sure how seriously I
> should take it.
That shouldn't be the problem.
> Thanks for any idea on what might be the cause or where to start digging.
Well, it sounds like the return address is being unwound incorrectly.
You may want to take a look at the CFI data by hand, and then compare
with dwarf2_frame_prev_register. I can't quite imagine how you'd get
the one-instruction-early behavior, though :)
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-19 0:09 ` Orjan Friberg
@ 2004-03-11 14:09 ` Orjan Friberg
2004-03-11 15:55 ` Orjan Friberg
1 sibling, 0 replies; 36+ messages in thread
From: Orjan Friberg @ 2004-03-11 14:09 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
Daniel Jacobowitz wrote:
>
> Well, it sounds like the return address is being unwound incorrectly.
> You may want to take a look at the CFI data by hand, and then compare
> with dwarf2_frame_prev_register. I can't quite imagine how you'd get
> the one-instruction-early behavior, though :)
(The "one-instruction-early" description of the breakpoint setting was
incorrect - that breakpoint was actually the "break main" breakpoint.
Thanks for noticing.)
The test program is just:
void foo(void) {}
int main ()
{
foo();
return 0;
}
Here's what happens when I do "next" over the call to foo():
dwarf2_frame_prev_register gets called for register 15 (PC). The switch
on cache->reg[regnum].how leads to DWARF2_FRAME_REG_SAVED_REG, where
cache->reg[regnum].loc.reg says the PC is located in register 16, so we
unwind register 16 from the next frame, which is definitely wrong
(register 16 is a 8-bit zero register). Changing 16 to 27 (SRP, where
the PC is saved) makes "next" work in this simple case.
I did a readelf -w on the binary (below), and looked at the
.debug_frame-section (hoping that's what you meant by "look at the CFI
data by hand"), and though my understanding of this is limited I get the
impression that the dwarf2 CFI for CRIS is wrong (but that the dwarf2
frame unwinder does the right thing). "Return address column" says 16,
and for main (where the SRP is pushed on the stack) it says
"DW_CFA_offset: r16 at cfa-4".
I checked section 6.4.1 in the dwarf2 standard, but I couldn't confirm
my suspicions since some of the fields mentioned weren't present in the
readelf output (return_address_register for example).
00000010 0000000c ffffffff CIE
Version: 1
Augmentation: ""
Code alignment factor: 1
Data alignment factor: -1
Return address column: 16
DW_CFA_def_cfa: r14 ofs 0
00000020 00000014 00000010 FDE cie=00000010 pc=000802e4..000802f0
DW_CFA_advance_loc: 0 to 000802e4
DW_CFA_def_cfa: r8 ofs 4
DW_CFA_offset: r8 at cfa-4
DW_CFA_nop
DW_CFA_nop
00000038 00000014 00000010 FDE cie=00000010 pc=000802f0..0008030a
DW_CFA_advance_loc: 0 to 000802f0
DW_CFA_def_cfa: r8 ofs 8
DW_CFA_offset: r16 at cfa-4
DW_CFA_offset: r8 at cfa-8
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-19 0:09 ` Orjan Friberg
2004-03-11 14:09 ` Orjan Friberg
@ 2004-03-11 15:55 ` Orjan Friberg
2004-03-11 17:05 ` Andrew Cagney
` (2 more replies)
1 sibling, 3 replies; 36+ messages in thread
From: Orjan Friberg @ 2004-03-11 15:55 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
I don't know if this is related to the previous suggested problem (i.e.
the dwarf2 information being wrong), but I changed the test program
slightly to:
void bar(void) {}
void foo(void)
{
bar();
}
int main ()
{
foo();
return 0;
}
Now foo is no longer a leaf function, and thus saves the return address
on the stack in its prologue. Stepping over foo ("next" in main) causes
a breakpoint to be set at the first instruction in foo. After the
target is stopped at that instruction (which is where the return address
is pushed on the stack) dwarf2_frame_prev_register is called, which
thinks that the PC is saved on the stack (case
DWARF2_FRAME_REG_SAVED_OFFSET) and reads it from there. Obviously the
value it reads is wrong, since the return address hasn't been pushed yet.
What's wrong here? Is the dwarf2 debug information wrong, or should
dwarf2_frame_prev_register not have been called while still in the prologue?
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-11 15:55 ` Orjan Friberg
@ 2004-03-11 17:05 ` Andrew Cagney
2004-03-19 0:09 ` Orjan Friberg
2004-03-19 0:09 ` Andrew Cagney
2004-03-11 17:11 ` Daniel Jacobowitz
2004-03-19 0:09 ` Orjan Friberg
2 siblings, 2 replies; 36+ messages in thread
From: Andrew Cagney @ 2004-03-11 17:05 UTC (permalink / raw)
To: Orjan Friberg; +Cc: Daniel Jacobowitz, gdb-patches
> I don't know if this is related to the previous suggested problem (i.e. the dwarf2 information being wrong), but I changed the test program slightly to:
>
> void bar(void) {}
> void foo(void)
> {
> bar();
> }
> int main ()
> {
> foo();
> return 0;
> }
>
> Now foo is no longer a leaf function, and thus saves the return address on the stack in its prologue. Stepping over foo ("next" in main) causes a breakpoint to be set at the first instruction in foo. After the target is stopped at that instruction (which is where the return address is pushed on the stack) dwarf2_frame_prev_register is called, which thinks that the PC is saved on the stack (case DWARF2_FRAME_REG_SAVED_OFFSET) and reads it from there. Obviously the value it reads is wrong, since the return address hasn't been pushed yet.
>
> What's wrong here? Is the dwarf2 debug information wrong, or should dwarf2_frame_prev_register not have been called while still in the prologue?
Does this:
/* NOTE: cagney/2003-09-05: CFI should specify the disposition
of all debug info registers. If it doesn't, complain (but
not too loudly). It turns out that GCC assumes that an
unspecified register implies "same value" when CFI (draft
7) specifies nothing at all. Such a register could equally
be interpreted as "undefined". Also note that this check
isn't sufficient; it only checks that all registers in the
range [0 .. max column] are specified, and won't detect
problems when a debug info register falls outside of the
table. We need a way of iterating through all the valid
DWARF2 register numbers. */
if (fs->regs.reg[column].how == DWARF2_FRAME_REG_UNSPECIFIED)
complaint (&symfile_complaints,
"Incomplete CFI data; unspecified registers at 0x%s",
paddr (fs->pc));
else
cache->reg[regnum] = fs->regs.reg[column];
sound like your problem? It's possible to specify initial values of
such registers with:
/* Set the architecture-specific register state initialization
function for GDBARCH to INIT_REG. */
extern void dwarf2_frame_set_init_reg (struct gdbarch *gdbarch,
void (*init_reg) (struct gdbarch
*, int,
struct
dwarf2_frame_state_reg *));
Andrew
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-11 15:55 ` Orjan Friberg
2004-03-11 17:05 ` Andrew Cagney
@ 2004-03-11 17:11 ` Daniel Jacobowitz
2004-03-12 10:23 ` Orjan Friberg
2004-03-19 0:09 ` Daniel Jacobowitz
2004-03-19 0:09 ` Orjan Friberg
2 siblings, 2 replies; 36+ messages in thread
From: Daniel Jacobowitz @ 2004-03-11 17:11 UTC (permalink / raw)
To: Orjan Friberg; +Cc: gdb-patches
On Thu, Mar 11, 2004 at 04:55:04PM +0100, Orjan Friberg wrote:
> I don't know if this is related to the previous suggested problem (i.e.
> the dwarf2 information being wrong), but I changed the test program
> slightly to:
>
> void bar(void) {}
> void foo(void)
> {
> bar();
> }
> int main ()
> {
> foo();
> return 0;
> }
>
> Now foo is no longer a leaf function, and thus saves the return address
> on the stack in its prologue. Stepping over foo ("next" in main) causes
> a breakpoint to be set at the first instruction in foo. After the
> target is stopped at that instruction (which is where the return address
> is pushed on the stack) dwarf2_frame_prev_register is called, which
> thinks that the PC is saved on the stack (case
> DWARF2_FRAME_REG_SAVED_OFFSET) and reads it from there. Obviously the
> value it reads is wrong, since the return address hasn't been pushed yet.
>
> What's wrong here? Is the dwarf2 debug information wrong, or should
> dwarf2_frame_prev_register not have been called while still in the prologue?
The beauty of using the CFI data is that it _is_ supposed to work in
the prologue. It sounds like the CFI is wrong. Could you post both
assembly and CFI data for the same testcase? I don't know CRIS
assembly but I imagine I can interpret it well enough to see what's
going on.
It also sounds like your DWARF2_REG_TO_REGNUM may need work, if the
unwinder thinks r16 is the return address column and GDB thinks it's an
8-bit register.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-11 17:11 ` Daniel Jacobowitz
@ 2004-03-12 10:23 ` Orjan Friberg
2004-03-19 0:09 ` Daniel Jacobowitz
` (3 more replies)
2004-03-19 0:09 ` Daniel Jacobowitz
1 sibling, 4 replies; 36+ messages in thread
From: Orjan Friberg @ 2004-03-12 10:23 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1192 bytes --]
Daniel Jacobowitz wrote:
>
> The beauty of using the CFI data is that it _is_ supposed to work in
> the prologue. It sounds like the CFI is wrong. Could you post both
> assembly and CFI data for the same testcase? I don't know CRIS
> assembly but I imagine I can interpret it well enough to see what's
> going on.
I have attached the test program, dissassembly (objdump -d -S) and the
dwarf2 info (readelf -w). (Crash course in CRIS assembly, if at all
needed: r8 holds the frame pointer and srp holds the return address,
pushed only in non-leaf functions.)
> It also sounds like your DWARF2_REG_TO_REGNUM may need work, if the
> unwinder thinks r16 is the return address column and GDB thinks it's an
> 8-bit register.
Ugh, I had totally missed that (i.e. I don't even have a CRIS-specific
DWARF2_REG_TO_REGNUM). Looking at the other targets' implementations I
don't understand where they got the dwarf2 register mapping from (though
amd64-tdep.c mentions System V psABI), and the dwarf2 spec says in
"2.4.2 Register Name Operators" it should be in the architecture's ABI
spec. I'll go bug my compiler guy, or go look in gcc myself.
--
Orjan Friberg
Axis Communications
[-- Attachment #2: test.c --]
[-- Type: text/x-csrc, Size: 84 bytes --]
void bar(void) {}
void foo(void)
{
bar();
}
int main ()
{
foo();
return 0;
}
[-- Attachment #3: disassembly --]
[-- Type: text/plain, Size: 1102 bytes --]
test: file format elf32-cris
Disassembly of section .text:
00080074 <bar>:
void bar(void) {}
80074: fce1 ee8f push $r8
80078: 6e86 move.d $sp,$r8
8007a: 68e6 move.d $r8,$sp
8007c: 7fb6 ret
8007e: 6e8e pop $r8
00080080 <foo>:
void foo(void)
{
80080: fce1 7ebe push $srp
80084: fce1 ee8f push $r8
80088: 6e86 move.d $sp,$r8
bar();
8008a: 3fbd 7400 0800 jsr 80074 <bar>
}
80090: 68e6 move.d $r8,$sp
80092: 6e8e pop $r8
80094: 3e0d jump [$sp+]
00080096 <main>:
int main ()
{
80096: fce1 7ebe push $srp
8009a: fce1 ee8f push $r8
8009e: 6e86 move.d $sp,$r8
foo();
800a0: 3fbd 8000 0800 jsr 80080 <foo>
return 0;
800a6: 7986 clear.d $r9
}
800a8: 69a6 move.d $r9,$r10
800aa: 68e6 move.d $r8,$sp
800ac: 6e8e pop $r8
800ae: 3e0d jump [$sp+]
[-- Attachment #4: dwarf2info --]
[-- Type: text/plain, Size: 5843 bytes --]
The section .debug_aranges contains:
Length: 28
Version: 2
Offset into .debug_info: 0
Pointer Size: 4
Segment Size: 0
Address Length
00080074 60
Contents of the .debug_pubnames section:
Length: 39
Version: 2
Offset into .debug_info section: 0
Size of area in .debug_info section: 105
Offset Name
37 bar
56 foo
75 main
The section .debug_info contains:
Compilation Unit @ 0:
Length: 101
Version: 2
Abbrev Offset: 0
Pointer Size: 4
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
DW_AT_stmt_list : 0
DW_AT_high_pc : 0x800b0 524464
DW_AT_low_pc : 0x80074 524404
DW_AT_name : (indirect string, offset: 0x34): test.c
DW_AT_comp_dir : (indirect string, offset: 0x0): /home/orjanf
DW_AT_producer : (indirect string, offset: 0xd): GNU C 3.2.1 Axis release R55/1.55
DW_AT_language : 1 (ANSI C)
<1><25>: Abbrev Number: 2 (DW_TAG_subprogram)
DW_AT_external : 1
DW_AT_name : bar
DW_AT_decl_file : 1
DW_AT_decl_line : 1
DW_AT_prototyped : 1
DW_AT_low_pc : 0x80074 524404
DW_AT_high_pc : 0x80080 524416
DW_AT_frame_base : 1 byte block: 58 (DW_OP_reg8; )
<1><38>: Abbrev Number: 2 (DW_TAG_subprogram)
DW_AT_external : 1
DW_AT_name : foo
DW_AT_decl_file : 1
DW_AT_decl_line : 3
DW_AT_prototyped : 1
DW_AT_low_pc : 0x80080 524416
DW_AT_high_pc : 0x80096 524438
DW_AT_frame_base : 1 byte block: 58 (DW_OP_reg8; )
<1><4b>: Abbrev Number: 3 (DW_TAG_subprogram)
DW_AT_external : 1
DW_AT_name : (indirect string, offset: 0x2f): main
DW_AT_decl_file : 1
DW_AT_decl_line : 7
DW_AT_type : <61>
DW_AT_low_pc : 0x80096 524438
DW_AT_high_pc : 0x800b0 524464
DW_AT_frame_base : 1 byte block: 58 (DW_OP_reg8; )
<1><61>: Abbrev Number: 4 (DW_TAG_base_type)
DW_AT_name : int
DW_AT_byte_size : 4
DW_AT_encoding : 5 (signed)
Contents of the .debug_abbrev section:
Number TAG
1 DW_TAG_compile_unit [has children]
DW_AT_stmt_list DW_FORM_data4
DW_AT_high_pc DW_FORM_addr
DW_AT_low_pc DW_FORM_addr
DW_AT_name DW_FORM_strp
DW_AT_comp_dir DW_FORM_strp
DW_AT_producer DW_FORM_strp
DW_AT_language DW_FORM_data1
2 DW_TAG_subprogram [no children]
DW_AT_external DW_FORM_flag
DW_AT_name DW_FORM_string
DW_AT_decl_file DW_FORM_data1
DW_AT_decl_line DW_FORM_data1
DW_AT_prototyped DW_FORM_flag
DW_AT_low_pc DW_FORM_addr
DW_AT_high_pc DW_FORM_addr
DW_AT_frame_base DW_FORM_block1
3 DW_TAG_subprogram [no children]
DW_AT_external DW_FORM_flag
DW_AT_name DW_FORM_strp
DW_AT_decl_file DW_FORM_data1
DW_AT_decl_line DW_FORM_data1
DW_AT_type DW_FORM_ref4
DW_AT_low_pc DW_FORM_addr
DW_AT_high_pc DW_FORM_addr
DW_AT_frame_base DW_FORM_block1
4 DW_TAG_base_type [no children]
DW_AT_name DW_FORM_string
DW_AT_byte_size DW_FORM_data1
DW_AT_encoding DW_FORM_data1
Dump of debug contents of section .debug_line:
Length: 52
DWARF Version: 2
Prologue Length: 26
Minimum Instruction Length: 2
Initial value of 'is_stmt': 1
Line Base: -5
Line Range: 14
Opcode Base: 10
Opcodes:
Opcode 1 has 0 args
Opcode 2 has 1 args
Opcode 3 has 1 args
Opcode 4 has 1 args
Opcode 5 has 1 args
Opcode 6 has 0 args
Opcode 7 has 0 args
Opcode 8 has 0 args
Opcode 9 has 1 args
The Directory Table is empty.
The File Name Table:
Entry Dir Time Size Name
1 0 0 0 test.c
Line Number Statements:
Extended opcode 2: set Address to 0x80074
Special opcode 5: advance Address by 0 to 0x80074 and Line by 0 to 1
Special opcode 91: advance Address by 12 to 0x80080 and Line by 2 to 3
Special opcode 76: advance Address by 10 to 0x8008a and Line by 1 to 4
Special opcode 48: advance Address by 6 to 0x80090 and Line by 1 to 5
Special opcode 49: advance Address by 6 to 0x80096 and Line by 2 to 7
Special opcode 76: advance Address by 10 to 0x800a0 and Line by 1 to 8
Special opcode 48: advance Address by 6 to 0x800a6 and Line by 1 to 9
Special opcode 20: advance Address by 2 to 0x800a8 and Line by 1 to 10
Advance PC by 8 to 800b0
Extended opcode 1: End of Sequence
The section .debug_frame contains:
00000000 0000000c ffffffff CIE
Version: 1
Augmentation: ""
Code alignment factor: 1
Data alignment factor: -1
Return address column: 16
DW_CFA_def_cfa: r14 ofs 0
00000010 00000014 00000000 FDE cie=00000000 pc=00080074..00080080
DW_CFA_advance_loc: 0 to 00080074
DW_CFA_def_cfa: r8 ofs 4
DW_CFA_offset: r8 at cfa-4
DW_CFA_nop
DW_CFA_nop
00000028 00000014 00000000 FDE cie=00000000 pc=00080080..00080096
DW_CFA_advance_loc: 0 to 00080080
DW_CFA_def_cfa: r8 ofs 8
DW_CFA_offset: r16 at cfa-4
DW_CFA_offset: r8 at cfa-8
00000040 00000014 00000000 FDE cie=00000000 pc=00080096..000800b0
DW_CFA_advance_loc: 0 to 00080096
DW_CFA_def_cfa: r8 ofs 8
DW_CFA_offset: r16 at cfa-4
DW_CFA_offset: r8 at cfa-8
Contents of the .debug_str section:
0x00000000 2f686f6d 652f6f72 6a616e66 00474e55 /home/orjanf.GNU
0x00000010 20432033 2e322e31 20417869 73207265 C 3.2.1 Axis re
0x00000020 6c656173 65205235 352f312e 3535006d lease R55/1.55.m
0x00000030 61696e00 74657374 2e6300 ain.test.c.
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-19 0:09 ` Orjan Friberg
@ 2004-03-12 12:00 ` Orjan Friberg
0 siblings, 0 replies; 36+ messages in thread
From: Orjan Friberg @ 2004-03-12 12:00 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Daniel Jacobowitz, gdb-patches
Andrew Cagney wrote:
>
> Does this:
>
> /* NOTE: cagney/2003-09-05: CFI should specify the disposition
> of all debug info registers. If it doesn't, complain (but
> not too loudly). It turns out that GCC assumes that an
> unspecified register implies "same value" when CFI (draft
> 7) specifies nothing at all. Such a register could equally
> be interpreted as "undefined". Also note that this check
> isn't sufficient; it only checks that all registers in the
> range [0 .. max column] are specified, and won't detect
> problems when a debug info register falls outside of the
> table. We need a way of iterating through all the valid
> DWARF2 register numbers. */
> if (fs->regs.reg[column].how == DWARF2_FRAME_REG_UNSPECIFIED)
> complaint (&symfile_complaints,
> "Incomplete CFI data; unspecified registers at 0x%s",
> paddr (fs->pc));
> else
> cache->reg[regnum] = fs->regs.reg[column];
>
> sound like your problem? It's possible to specify initial values of
> such registers with:
I do get that complaint, and it seems a lot of registers are set to
DWARF2_FRAME_REG_UNSPECIFIED.
> /* Set the architecture-specific register state initialization
> function for GDBARCH to INIT_REG. */
>
> extern void dwarf2_frame_set_init_reg (struct gdbarch *gdbarch,
> void (*init_reg) (struct gdbarch
> *, int,
> struct
> dwarf2_frame_state_reg *));
Thanks for the tip, I hadn't seen that. Reading the s390 implementation
of dwarf2_frame_init_reg I get the impression that that information
should have been there from the beginning (emitted by gcc that is) since
it seems to be ABI/calling convention related. But I'll try and
implement something similar.
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-19 0:09 ` Orjan Friberg
@ 2004-03-12 13:50 ` Orjan Friberg
0 siblings, 0 replies; 36+ messages in thread
From: Orjan Friberg @ 2004-03-12 13:50 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
Orjan Friberg wrote:
> Ugh, I had totally missed that (i.e. I don't even have a CRIS-specific
> DWARF2_REG_TO_REGNUM). Looking at the other targets' implementations I
> don't understand where they got the dwarf2 register mapping from (though
> amd64-tdep.c mentions System V psABI), and the dwarf2 spec says in
> "2.4.2 Register Name Operators" it should be in the architecture's ABI
> spec. I'll go bug my compiler guy, or go look in gcc myself.
Too trigger happy on the send button... The mn10300 told me where to
find it (gcc/config/cris/cris.h). It seems only the SRP needs special
handling (besides the ones that aren't mapped at all).
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-19 0:09 ` Daniel Jacobowitz
@ 2004-03-12 15:38 ` Daniel Jacobowitz
2004-03-15 10:19 ` Orjan Friberg
2004-03-16 16:26 ` Orjan Friberg
2 siblings, 0 replies; 36+ messages in thread
From: Daniel Jacobowitz @ 2004-03-12 15:38 UTC (permalink / raw)
To: Orjan Friberg; +Cc: gdb-patches
On Fri, Mar 12, 2004 at 11:22:34AM +0100, Orjan Friberg wrote:
> Daniel Jacobowitz wrote:
> >
> >The beauty of using the CFI data is that it _is_ supposed to work in
> >the prologue. It sounds like the CFI is wrong. Could you post both
> >assembly and CFI data for the same testcase? I don't know CRIS
> >assembly but I imagine I can interpret it well enough to see what's
> >going on.
>
> I have attached the test program, dissassembly (objdump -d -S) and the
> dwarf2 info (readelf -w). (Crash course in CRIS assembly, if at all
> needed: r8 holds the frame pointer and srp holds the return address,
> pushed only in non-leaf functions.)
OK, let's see what we have. I can see that your unwind information is
definitely wrong. Take a look at this:
00080080 <foo>:
void foo(void)
{
80080: fce1 7ebe push $srp
80084: fce1 ee8f push $r8
80088: 6e86 move.d $sp,$r8
bar();
8008a: 3fbd 7400 0800 jsr 80074 <bar>
}
80090: 68e6 move.d $r8,$sp
80092: 6e8e pop $r8
80094: 3e0d jump [$sp+]
00000028 00000014 00000000 FDE cie=00000000 pc=00080080..00080096
DW_CFA_advance_loc: 0 to 00080080
DW_CFA_def_cfa: r8 ofs 8
DW_CFA_offset: r16 at cfa-4
DW_CFA_offset: r8 at cfa-8
That says, at 0x80080, CFA is r8 + 8 and both r16 and r8 are saved.
Which is obviously untrue.
I see that your GCC port uses textual prologues. As it happens, I just
implemented dwarf generation for that mechanism (for Thumb), so I know
how it's supposed to work. Here's your problem. First you have:
/* FIXME: Slightly redundant calculation, as we do the same in
pieces below. This offset must be the total adjustment of the
stack-pointer. We can then def_cfa call at the end of this
function with the current implementation of execute_cfa_insn, but
that wouldn't really be clean. */
cfa_label = dwarf2out_cfi_label ();
dwarf2out_def_cfa (cfa_label, cfa_reg, cfa_offset);
but that label is at the beginning of the function, so this is
incorrect. That's not what the CFA is at the beginning of the
function.
What it really ought to be, if I'm reading this right, is (I'll use the
gas CFI pseudo-ops to write this, but you'd use GCC's internal
mechanism to emit it...)
00080080 <foo>:
.cfi_startproc
.cfi_def_cfa $sp, 0 # Set the CFA to $sp + 0
80080: fce1 7ebe push $srp
.cfi_def_cfa_offset 4
.cfi_offset $srp, -4
80084: fce1 ee8f push $r8
.cfi_def_cfa_offset 8
.cfi_offset $r8, -8
80088: 6e86 move.d $sp,$r8
.cfi_def_cfa $r8, 0
With that sequence, assuming that I didn't make any silly mistakes, the
CFI is correct at every instruction.
>
> >It also sounds like your DWARF2_REG_TO_REGNUM may need work, if the
> >unwinder thinks r16 is the return address column and GDB thinks it's an
> >8-bit register.
>
> Ugh, I had totally missed that (i.e. I don't even have a CRIS-specific
> DWARF2_REG_TO_REGNUM). Looking at the other targets' implementations I
> don't understand where they got the dwarf2 register mapping from (though
> amd64-tdep.c mentions System V psABI), and the dwarf2 spec says in
> "2.4.2 Register Name Operators" it should be in the architecture's ABI
> spec. I'll go bug my compiler guy, or go look in gcc myself.
>
> --
> Orjan Friberg
> Axis Communications
>
>
> test: file format elf32-cris
>
> Disassembly of section .text:
>
> 00080074 <bar>:
> void bar(void) {}
> 80074: fce1 ee8f push $r8
> 80078: 6e86 move.d $sp,$r8
> 8007a: 68e6 move.d $r8,$sp
> 8007c: 7fb6 ret
> 8007e: 6e8e pop $r8
>
> 00080080 <foo>:
> void foo(void)
> {
> 80080: fce1 7ebe push $srp
> 80084: fce1 ee8f push $r8
> 80088: 6e86 move.d $sp,$r8
> bar();
> 8008a: 3fbd 7400 0800 jsr 80074 <bar>
> }
> 80090: 68e6 move.d $r8,$sp
> 80092: 6e8e pop $r8
> 80094: 3e0d jump [$sp+]
>
> 00080096 <main>:
> int main ()
> {
> 80096: fce1 7ebe push $srp
> 8009a: fce1 ee8f push $r8
> 8009e: 6e86 move.d $sp,$r8
> foo();
> 800a0: 3fbd 8000 0800 jsr 80080 <foo>
> return 0;
> 800a6: 7986 clear.d $r9
> }
> 800a8: 69a6 move.d $r9,$r10
> 800aa: 68e6 move.d $r8,$sp
> 800ac: 6e8e pop $r8
> 800ae: 3e0d jump [$sp+]
> The section .debug_aranges contains:
>
> Length: 28
> Version: 2
> Offset into .debug_info: 0
> Pointer Size: 4
> Segment Size: 0
>
> Address Length
> 00080074 60
>
> Contents of the .debug_pubnames section:
>
> Length: 39
> Version: 2
> Offset into .debug_info section: 0
> Size of area in .debug_info section: 105
>
> Offset Name
> 37 bar
> 56 foo
> 75 main
>
> The section .debug_info contains:
>
> Compilation Unit @ 0:
> Length: 101
> Version: 2
> Abbrev Offset: 0
> Pointer Size: 4
> <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
> DW_AT_stmt_list : 0
> DW_AT_high_pc : 0x800b0 524464
> DW_AT_low_pc : 0x80074 524404
> DW_AT_name : (indirect string, offset: 0x34): test.c
> DW_AT_comp_dir : (indirect string, offset: 0x0): /home/orjanf
> DW_AT_producer : (indirect string, offset: 0xd): GNU C 3.2.1 Axis release R55/1.55
> DW_AT_language : 1 (ANSI C)
> <1><25>: Abbrev Number: 2 (DW_TAG_subprogram)
> DW_AT_external : 1
> DW_AT_name : bar
> DW_AT_decl_file : 1
> DW_AT_decl_line : 1
> DW_AT_prototyped : 1
> DW_AT_low_pc : 0x80074 524404
> DW_AT_high_pc : 0x80080 524416
> DW_AT_frame_base : 1 byte block: 58 (DW_OP_reg8; )
> <1><38>: Abbrev Number: 2 (DW_TAG_subprogram)
> DW_AT_external : 1
> DW_AT_name : foo
> DW_AT_decl_file : 1
> DW_AT_decl_line : 3
> DW_AT_prototyped : 1
> DW_AT_low_pc : 0x80080 524416
> DW_AT_high_pc : 0x80096 524438
> DW_AT_frame_base : 1 byte block: 58 (DW_OP_reg8; )
> <1><4b>: Abbrev Number: 3 (DW_TAG_subprogram)
> DW_AT_external : 1
> DW_AT_name : (indirect string, offset: 0x2f): main
> DW_AT_decl_file : 1
> DW_AT_decl_line : 7
> DW_AT_type : <61>
> DW_AT_low_pc : 0x80096 524438
> DW_AT_high_pc : 0x800b0 524464
> DW_AT_frame_base : 1 byte block: 58 (DW_OP_reg8; )
> <1><61>: Abbrev Number: 4 (DW_TAG_base_type)
> DW_AT_name : int
> DW_AT_byte_size : 4
> DW_AT_encoding : 5 (signed)
>
> Contents of the .debug_abbrev section:
>
> Number TAG
> 1 DW_TAG_compile_unit [has children]
> DW_AT_stmt_list DW_FORM_data4
> DW_AT_high_pc DW_FORM_addr
> DW_AT_low_pc DW_FORM_addr
> DW_AT_name DW_FORM_strp
> DW_AT_comp_dir DW_FORM_strp
> DW_AT_producer DW_FORM_strp
> DW_AT_language DW_FORM_data1
> 2 DW_TAG_subprogram [no children]
> DW_AT_external DW_FORM_flag
> DW_AT_name DW_FORM_string
> DW_AT_decl_file DW_FORM_data1
> DW_AT_decl_line DW_FORM_data1
> DW_AT_prototyped DW_FORM_flag
> DW_AT_low_pc DW_FORM_addr
> DW_AT_high_pc DW_FORM_addr
> DW_AT_frame_base DW_FORM_block1
> 3 DW_TAG_subprogram [no children]
> DW_AT_external DW_FORM_flag
> DW_AT_name DW_FORM_strp
> DW_AT_decl_file DW_FORM_data1
> DW_AT_decl_line DW_FORM_data1
> DW_AT_type DW_FORM_ref4
> DW_AT_low_pc DW_FORM_addr
> DW_AT_high_pc DW_FORM_addr
> DW_AT_frame_base DW_FORM_block1
> 4 DW_TAG_base_type [no children]
> DW_AT_name DW_FORM_string
> DW_AT_byte_size DW_FORM_data1
> DW_AT_encoding DW_FORM_data1
>
>
> Dump of debug contents of section .debug_line:
>
> Length: 52
> DWARF Version: 2
> Prologue Length: 26
> Minimum Instruction Length: 2
> Initial value of 'is_stmt': 1
> Line Base: -5
> Line Range: 14
> Opcode Base: 10
>
> Opcodes:
> Opcode 1 has 0 args
> Opcode 2 has 1 args
> Opcode 3 has 1 args
> Opcode 4 has 1 args
> Opcode 5 has 1 args
> Opcode 6 has 0 args
> Opcode 7 has 0 args
> Opcode 8 has 0 args
> Opcode 9 has 1 args
>
> The Directory Table is empty.
>
> The File Name Table:
> Entry Dir Time Size Name
> 1 0 0 0 test.c
>
> Line Number Statements:
> Extended opcode 2: set Address to 0x80074
> Special opcode 5: advance Address by 0 to 0x80074 and Line by 0 to 1
> Special opcode 91: advance Address by 12 to 0x80080 and Line by 2 to 3
> Special opcode 76: advance Address by 10 to 0x8008a and Line by 1 to 4
> Special opcode 48: advance Address by 6 to 0x80090 and Line by 1 to 5
> Special opcode 49: advance Address by 6 to 0x80096 and Line by 2 to 7
> Special opcode 76: advance Address by 10 to 0x800a0 and Line by 1 to 8
> Special opcode 48: advance Address by 6 to 0x800a6 and Line by 1 to 9
> Special opcode 20: advance Address by 2 to 0x800a8 and Line by 1 to 10
> Advance PC by 8 to 800b0
> Extended opcode 1: End of Sequence
>
>
> The section .debug_frame contains:
>
> 00000000 0000000c ffffffff CIE
> Version: 1
> Augmentation: ""
> Code alignment factor: 1
> Data alignment factor: -1
> Return address column: 16
>
> DW_CFA_def_cfa: r14 ofs 0
>
> 00000010 00000014 00000000 FDE cie=00000000 pc=00080074..00080080
> DW_CFA_advance_loc: 0 to 00080074
> DW_CFA_def_cfa: r8 ofs 4
> DW_CFA_offset: r8 at cfa-4
> DW_CFA_nop
> DW_CFA_nop
>
> 00000028 00000014 00000000 FDE cie=00000000 pc=00080080..00080096
> DW_CFA_advance_loc: 0 to 00080080
> DW_CFA_def_cfa: r8 ofs 8
> DW_CFA_offset: r16 at cfa-4
> DW_CFA_offset: r8 at cfa-8
>
> 00000040 00000014 00000000 FDE cie=00000000 pc=00080096..000800b0
> DW_CFA_advance_loc: 0 to 00080096
> DW_CFA_def_cfa: r8 ofs 8
> DW_CFA_offset: r16 at cfa-4
> DW_CFA_offset: r8 at cfa-8
>
> Contents of the .debug_str section:
>
> 0x00000000 2f686f6d 652f6f72 6a616e66 00474e55 /home/orjanf.GNU
> 0x00000010 20432033 2e322e31 20417869 73207265 C 3.2.1 Axis re
> 0x00000020 6c656173 65205235 352f312e 3535006d lease R55/1.55.m
> 0x00000030 61696e00 74657374 2e6300 ain.test.c.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-19 0:09 ` Orjan Friberg
@ 2004-03-12 15:38 ` Orjan Friberg
0 siblings, 0 replies; 36+ messages in thread
From: Orjan Friberg @ 2004-03-12 15:38 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
Orjan Friberg wrote:
> Daniel Jacobowitz wrote:
>
>>
>> The beauty of using the CFI data is that it _is_ supposed to work in
>> the prologue. It sounds like the CFI is wrong. Could you post both
>> assembly and CFI data for the same testcase? I don't know CRIS
>> assembly but I imagine I can interpret it well enough to see what's
>> going on.
Out of curiosity, I had a look at the calls to execute_cfa_program
(where the current state of the registers seems to be built from the
dwarf2 information). The second call to execute_cfa_program is preceded
by the comment:
/* Then decode the insns in the FDE up to our target PC. */
When we get into execute_cfa_program we're stopped at the first
instruction in foo, and the pc variable in execute_cfa_program is set to
that value also. Nevertheless we parse *all* the information in that FDE:
> 00000028 00000014 00000000 FDE cie=00000000 pc=00080080..00080096
> DW_CFA_advance_loc: 0 to 00080080
> DW_CFA_def_cfa: r8 ofs 8
> DW_CFA_offset: r16 at cfa-4
> DW_CFA_offset: r8 at cfa-8
So, not only do we incorrectly conclude that the SRP is located on the
stack, but that the frame pointer (r8) is also (though neither of those
have actually been pushed yet). Comparing with the example in Appendix
5 of the dwarf2 spec I get the impression that some DW_CFA_advance_loc
are missing, but now is probably a good time for me to stop guessing ;-) .
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-19 0:09 ` Daniel Jacobowitz
2004-03-12 15:38 ` Daniel Jacobowitz
@ 2004-03-15 10:19 ` Orjan Friberg
2004-03-19 0:09 ` Orjan Friberg
2004-03-16 16:26 ` Orjan Friberg
2 siblings, 1 reply; 36+ messages in thread
From: Orjan Friberg @ 2004-03-15 10:19 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
Daniel Jacobowitz wrote:
>
> I see that your GCC port uses textual prologues. As it happens, I just
> implemented dwarf generation for that mechanism (for Thumb), so I know
> how it's supposed to work. Here's your problem. First you have:
Daniel,
Thanks a lot for your help - I've forwarded it to the gcc CRIS maintainer.
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-19 0:09 ` Daniel Jacobowitz
2004-03-12 15:38 ` Daniel Jacobowitz
2004-03-15 10:19 ` Orjan Friberg
@ 2004-03-16 16:26 ` Orjan Friberg
2004-03-16 19:13 ` Daniel Jacobowitz
2004-03-19 0:09 ` Orjan Friberg
2 siblings, 2 replies; 36+ messages in thread
From: Orjan Friberg @ 2004-03-16 16:26 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches, Hans-Peter Nilsson
Daniel Jacobowitz wrote:
>
> I see that your GCC port uses textual prologues. As it happens, I just
> implemented dwarf generation for that mechanism (for Thumb), so I know
> how it's supposed to work. Here's your problem. First you have:
>
> /* FIXME: Slightly redundant calculation, as we do the same in
> pieces below. This offset must be the total adjustment of the
> stack-pointer. We can then def_cfa call at the end of this
> function with the current implementation of execute_cfa_insn, but
> that wouldn't really be clean. */
>
> cfa_label = dwarf2out_cfi_label ();
> dwarf2out_def_cfa (cfa_label, cfa_reg, cfa_offset);
>
> but that label is at the beginning of the function, so this is
> incorrect. That's not what the CFA is at the beginning of the
> function.
Would emitting that label *after* the prologue be an option (i.e.
leaving us without dwarf2 information while still in the prologue)?
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-16 16:26 ` Orjan Friberg
@ 2004-03-16 19:13 ` Daniel Jacobowitz
2004-03-16 20:51 ` Hans-Peter Nilsson
2004-03-19 0:09 ` Daniel Jacobowitz
2004-03-19 0:09 ` Orjan Friberg
1 sibling, 2 replies; 36+ messages in thread
From: Daniel Jacobowitz @ 2004-03-16 19:13 UTC (permalink / raw)
To: Orjan Friberg; +Cc: gdb-patches, Hans-Peter Nilsson
On Tue, Mar 16, 2004 at 05:26:16PM +0100, Orjan Friberg wrote:
> Daniel Jacobowitz wrote:
> >
> >I see that your GCC port uses textual prologues. As it happens, I just
> >implemented dwarf generation for that mechanism (for Thumb), so I know
> >how it's supposed to work. Here's your problem. First you have:
> >
> > /* FIXME: Slightly redundant calculation, as we do the same in
> > pieces below. This offset must be the total adjustment of the
> > stack-pointer. We can then def_cfa call at the end of this
> > function with the current implementation of execute_cfa_insn, but
> > that wouldn't really be clean. */
> >
> > cfa_label = dwarf2out_cfi_label ();
> > dwarf2out_def_cfa (cfa_label, cfa_reg, cfa_offset);
> >
> >but that label is at the beginning of the function, so this is
> >incorrect. That's not what the CFA is at the beginning of the
> >function.
>
> Would emitting that label *after* the prologue be an option (i.e.
> leaving us without dwarf2 information while still in the prologue)?
Nope. Then when you step into the prologue (i.e. "step over") unwind
information will be incorrect.
I recommend taking a look at the patch where I implemented this for
Thumb, or at the m68k implementation.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-16 19:13 ` Daniel Jacobowitz
@ 2004-03-16 20:51 ` Hans-Peter Nilsson
2004-03-16 22:27 ` Daniel Jacobowitz
2004-03-19 0:09 ` Hans-Peter Nilsson
2004-03-19 0:09 ` Daniel Jacobowitz
1 sibling, 2 replies; 36+ messages in thread
From: Hans-Peter Nilsson @ 2004-03-16 20:51 UTC (permalink / raw)
To: drow; +Cc: orjan.friberg, gdb-patches, hans-peter.nilsson
> Date: Tue, 16 Mar 2004 14:13:01 -0500
> From: Daniel Jacobowitz <drow@false.org>
Hi Dan.
> On Tue, Mar 16, 2004 at 05:26:16PM +0100, Orjan Friberg wrote:
> > Would emitting that label *after* the prologue be an option (i.e.
> > leaving us without dwarf2 information while still in the prologue)?
>
> Nope. Then when you step into the prologue (i.e. "step over") unwind
> information will be incorrect.
Is that the whole effect, incorrectness for gdb usage *inside*
the prologue?
> I recommend taking a look at the patch where I implemented this for
> Thumb, or at the m68k implementation.
I know *how* to do it, I just want to prod a little if there's a
way to avoid dwarf2 info (specifically advance_loc directives)
not necessary for EH unwinding and still have it working for gdb
modulo stepping inside the prologue. It worked fine until gdb
started to use dwarf2 too. :-)
As you know, the same info ends up in the EH unwind info as
well, and we don't want that to be larger than absolutely
necessary. (And as I suppose you *also* know, mentioned for the
record, "disk is cheap" is definitely not true when the disk is
solid-state memory.) Yeah, there should be a way to emit
different dwarf2 EH from that for debug. Hmm, maybe it would
work to just withholding all advance_loc codes except the last
one for for_eh && !flag_asynchronous_unwind_tables in
gcc/dwarf2out.c (sort of). And a target-specific hook for
"advancing loc", which could use the new gas dwarf2 directives
so it's not always advance_loc4. Getting off-topic here...
brgds, H-P
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-16 20:51 ` Hans-Peter Nilsson
@ 2004-03-16 22:27 ` Daniel Jacobowitz
2004-03-16 23:38 ` Hans-Peter Nilsson
2004-03-19 0:09 ` Daniel Jacobowitz
2004-03-19 0:09 ` Hans-Peter Nilsson
1 sibling, 2 replies; 36+ messages in thread
From: Daniel Jacobowitz @ 2004-03-16 22:27 UTC (permalink / raw)
To: Hans-Peter Nilsson; +Cc: orjan.friberg, gdb-patches
On Tue, Mar 16, 2004 at 09:50:28PM +0100, Hans-Peter Nilsson wrote:
> > Date: Tue, 16 Mar 2004 14:13:01 -0500
> > From: Daniel Jacobowitz <drow@false.org>
>
> Hi Dan.
>
> > On Tue, Mar 16, 2004 at 05:26:16PM +0100, Orjan Friberg wrote:
> > > Would emitting that label *after* the prologue be an option (i.e.
> > > leaving us without dwarf2 information while still in the prologue)?
> >
> > Nope. Then when you step into the prologue (i.e. "step over") unwind
> > information will be incorrect.
>
> Is that the whole effect, incorrectness for gdb usage *inside*
> the prologue?
Probably yes. So backtraces will not be affected but every bit of
running is likely to misbehave.
> > I recommend taking a look at the patch where I implemented this for
> > Thumb, or at the m68k implementation.
>
> I know *how* to do it, I just want to prod a little if there's a
> way to avoid dwarf2 info (specifically advance_loc directives)
> not necessary for EH unwinding and still have it working for gdb
> modulo stepping inside the prologue. It worked fine until gdb
> started to use dwarf2 too. :-)
>
> As you know, the same info ends up in the EH unwind info as
> well, and we don't want that to be larger than absolutely
> necessary. (And as I suppose you *also* know, mentioned for the
> record, "disk is cheap" is definitely not true when the disk is
> solid-state memory.) Yeah, there should be a way to emit
> different dwarf2 EH from that for debug. Hmm, maybe it would
> work to just withholding all advance_loc codes except the last
> one for for_eh && !flag_asynchronous_unwind_tables in
> gcc/dwarf2out.c (sort of). And a target-specific hook for
> "advancing loc", which could use the new gas dwarf2 directives
> so it's not always advance_loc4. Getting off-topic here...
Yeah, that may be the best way to solve this - emit more info in the
.debug_frame than in .eh_frame, if you aren't supporting asynchronous
unwinding. Like throwing from signal handlers taken during prologues,
et cetera.
GDB gets _very_ cranky when unwind information is specified but not
correct.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-16 22:27 ` Daniel Jacobowitz
@ 2004-03-16 23:38 ` Hans-Peter Nilsson
2004-03-16 23:58 ` Daniel Jacobowitz
2004-03-19 0:09 ` Hans-Peter Nilsson
2004-03-19 0:09 ` Daniel Jacobowitz
1 sibling, 2 replies; 36+ messages in thread
From: Hans-Peter Nilsson @ 2004-03-16 23:38 UTC (permalink / raw)
To: drow; +Cc: hans-peter.nilsson, orjan.friberg, gdb-patches
> Date: Tue, 16 Mar 2004 17:27:09 -0500
> From: Daniel Jacobowitz <drow@false.org>
> On Tue, Mar 16, 2004 at 09:50:28PM +0100, Hans-Peter Nilsson wrote:
> > > Date: Tue, 16 Mar 2004 14:13:01 -0500
> > > From: Daniel Jacobowitz <drow@false.org>
> > > On Tue, Mar 16, 2004 at 05:26:16PM +0100, Orjan Friberg wrote:
> > > > Would emitting that label *after* the prologue be an option (i.e.
> > > > leaving us without dwarf2 information while still in the prologue)?
> > > Nope. Then when you step into the prologue (i.e. "step over") unwind
> > > information will be incorrect.
> > Is that the whole effect, incorrectness for gdb usage *inside*
> > the prologue?
>
> Probably yes. So backtraces will not be affected but every bit of
> running is likely to misbehave.
*When* do things go wrong? Is it all gdb run-type commands all
the time, or is it just when (manually) looking around after
(manually) doing "stepi" into the prologue but not out of it?
Something else? Just curious in case you have the answer at
hand; I'll try and pursue splitting up EH & debug info.
> > Yeah, there should be a way to emit
> > different dwarf2 EH from that for debug. Hmm, maybe it would
> > work to just withholding all advance_loc codes except the last
> > one for for_eh && !flag_asynchronous_unwind_tables in
> > gcc/dwarf2out.c (sort of). And a target-specific hook for
> > "advancing loc", which could use the new gas dwarf2 directives
> > so it's not always advance_loc4. Getting off-topic here...
>
> Yeah, that may be the best way to solve this - emit more info in the
> .debug_frame than in .eh_frame, if you aren't supporting asynchronous
> unwinding. Like throwing from signal handlers taken during prologues,
> et cetera.
Yeah, flag_asynchronous_unwind_tables means all that. ISTR Java
and Ada uses that, or should.
> GDB gets _very_ cranky when unwind information is specified but not
> correct.
Opportunities for improvements in the failure mode here? ;-)
brgds, H-P
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-16 23:38 ` Hans-Peter Nilsson
@ 2004-03-16 23:58 ` Daniel Jacobowitz
2004-03-19 0:09 ` Daniel Jacobowitz
2004-03-19 0:09 ` Hans-Peter Nilsson
1 sibling, 1 reply; 36+ messages in thread
From: Daniel Jacobowitz @ 2004-03-16 23:58 UTC (permalink / raw)
To: Hans-Peter Nilsson; +Cc: orjan.friberg, gdb-patches
On Wed, Mar 17, 2004 at 12:38:00AM +0100, Hans-Peter Nilsson wrote:
> > Date: Tue, 16 Mar 2004 17:27:09 -0500
> > From: Daniel Jacobowitz <drow@false.org>
>
> > On Tue, Mar 16, 2004 at 09:50:28PM +0100, Hans-Peter Nilsson wrote:
> > > > Date: Tue, 16 Mar 2004 14:13:01 -0500
> > > > From: Daniel Jacobowitz <drow@false.org>
> > > > On Tue, Mar 16, 2004 at 05:26:16PM +0100, Orjan Friberg wrote:
> > > > > Would emitting that label *after* the prologue be an option (i.e.
> > > > > leaving us without dwarf2 information while still in the prologue)?
> > > > Nope. Then when you step into the prologue (i.e. "step over") unwind
> > > > information will be incorrect.
> > > Is that the whole effect, incorrectness for gdb usage *inside*
> > > the prologue?
> >
> > Probably yes. So backtraces will not be affected but every bit of
> > running is likely to misbehave.
>
> *When* do things go wrong? Is it all gdb run-type commands all
> the time, or is it just when (manually) looking around after
> (manually) doing "stepi" into the prologue but not out of it?
> Something else? Just curious in case you have the answer at
> hand; I'll try and pursue splitting up EH & debug info.
When you use "next", at a function call, GDB will step - then after
that instruction, it will try to find the frame ID. And then it will
unwind to find the caller's frame ID, and step or breakpoint/continue
until we get back there. So you've lost if you don't have the ability
to unwind at the first instruction.
Same if you "step" over something you don't have debug info for.
I'm sure there are more things that will go wrong; I don't know how
much.
>
> > > Yeah, there should be a way to emit
> > > different dwarf2 EH from that for debug. Hmm, maybe it would
> > > work to just withholding all advance_loc codes except the last
> > > one for for_eh && !flag_asynchronous_unwind_tables in
> > > gcc/dwarf2out.c (sort of). And a target-specific hook for
> > > "advancing loc", which could use the new gas dwarf2 directives
> > > so it's not always advance_loc4. Getting off-topic here...
> >
> > Yeah, that may be the best way to solve this - emit more info in the
> > .debug_frame than in .eh_frame, if you aren't supporting asynchronous
> > unwinding. Like throwing from signal handlers taken during prologues,
> > et cetera.
>
> Yeah, flag_asynchronous_unwind_tables means all that. ISTR Java
> and Ada uses that, or should.
>
> > GDB gets _very_ cranky when unwind information is specified but not
> > correct.
>
> Opportunities for improvements in the failure mode here? ;-)
Not really. You have unwind info; we have to either trust it, or not.
It's not failing to unwind, it's unwinding and providing incorrect
information...
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-12 10:23 ` Orjan Friberg
@ 2004-03-19 0:09 ` Daniel Jacobowitz
2004-03-12 15:38 ` Daniel Jacobowitz
` (2 more replies)
2004-03-19 0:09 ` Orjan Friberg
` (2 subsequent siblings)
3 siblings, 3 replies; 36+ messages in thread
From: Daniel Jacobowitz @ 2004-03-19 0:09 UTC (permalink / raw)
To: Orjan Friberg; +Cc: gdb-patches
On Fri, Mar 12, 2004 at 11:22:34AM +0100, Orjan Friberg wrote:
> Daniel Jacobowitz wrote:
> >
> >The beauty of using the CFI data is that it _is_ supposed to work in
> >the prologue. It sounds like the CFI is wrong. Could you post both
> >assembly and CFI data for the same testcase? I don't know CRIS
> >assembly but I imagine I can interpret it well enough to see what's
> >going on.
>
> I have attached the test program, dissassembly (objdump -d -S) and the
> dwarf2 info (readelf -w). (Crash course in CRIS assembly, if at all
> needed: r8 holds the frame pointer and srp holds the return address,
> pushed only in non-leaf functions.)
OK, let's see what we have. I can see that your unwind information is
definitely wrong. Take a look at this:
00080080 <foo>:
void foo(void)
{
80080: fce1 7ebe push $srp
80084: fce1 ee8f push $r8
80088: 6e86 move.d $sp,$r8
bar();
8008a: 3fbd 7400 0800 jsr 80074 <bar>
}
80090: 68e6 move.d $r8,$sp
80092: 6e8e pop $r8
80094: 3e0d jump [$sp+]
00000028 00000014 00000000 FDE cie=00000000 pc=00080080..00080096
DW_CFA_advance_loc: 0 to 00080080
DW_CFA_def_cfa: r8 ofs 8
DW_CFA_offset: r16 at cfa-4
DW_CFA_offset: r8 at cfa-8
That says, at 0x80080, CFA is r8 + 8 and both r16 and r8 are saved.
Which is obviously untrue.
I see that your GCC port uses textual prologues. As it happens, I just
implemented dwarf generation for that mechanism (for Thumb), so I know
how it's supposed to work. Here's your problem. First you have:
/* FIXME: Slightly redundant calculation, as we do the same in
pieces below. This offset must be the total adjustment of the
stack-pointer. We can then def_cfa call at the end of this
function with the current implementation of execute_cfa_insn, but
that wouldn't really be clean. */
cfa_label = dwarf2out_cfi_label ();
dwarf2out_def_cfa (cfa_label, cfa_reg, cfa_offset);
but that label is at the beginning of the function, so this is
incorrect. That's not what the CFA is at the beginning of the
function.
What it really ought to be, if I'm reading this right, is (I'll use the
gas CFI pseudo-ops to write this, but you'd use GCC's internal
mechanism to emit it...)
00080080 <foo>:
.cfi_startproc
.cfi_def_cfa $sp, 0 # Set the CFA to $sp + 0
80080: fce1 7ebe push $srp
.cfi_def_cfa_offset 4
.cfi_offset $srp, -4
80084: fce1 ee8f push $r8
.cfi_def_cfa_offset 8
.cfi_offset $r8, -8
80088: 6e86 move.d $sp,$r8
.cfi_def_cfa $r8, 0
With that sequence, assuming that I didn't make any silly mistakes, the
CFI is correct at every instruction.
>
> >It also sounds like your DWARF2_REG_TO_REGNUM may need work, if the
> >unwinder thinks r16 is the return address column and GDB thinks it's an
> >8-bit register.
>
> Ugh, I had totally missed that (i.e. I don't even have a CRIS-specific
> DWARF2_REG_TO_REGNUM). Looking at the other targets' implementations I
> don't understand where they got the dwarf2 register mapping from (though
> amd64-tdep.c mentions System V psABI), and the dwarf2 spec says in
> "2.4.2 Register Name Operators" it should be in the architecture's ABI
> spec. I'll go bug my compiler guy, or go look in gcc myself.
>
> --
> Orjan Friberg
> Axis Communications
>
>
> test: file format elf32-cris
>
> Disassembly of section .text:
>
> 00080074 <bar>:
> void bar(void) {}
> 80074: fce1 ee8f push $r8
> 80078: 6e86 move.d $sp,$r8
> 8007a: 68e6 move.d $r8,$sp
> 8007c: 7fb6 ret
> 8007e: 6e8e pop $r8
>
> 00080080 <foo>:
> void foo(void)
> {
> 80080: fce1 7ebe push $srp
> 80084: fce1 ee8f push $r8
> 80088: 6e86 move.d $sp,$r8
> bar();
> 8008a: 3fbd 7400 0800 jsr 80074 <bar>
> }
> 80090: 68e6 move.d $r8,$sp
> 80092: 6e8e pop $r8
> 80094: 3e0d jump [$sp+]
>
> 00080096 <main>:
> int main ()
> {
> 80096: fce1 7ebe push $srp
> 8009a: fce1 ee8f push $r8
> 8009e: 6e86 move.d $sp,$r8
> foo();
> 800a0: 3fbd 8000 0800 jsr 80080 <foo>
> return 0;
> 800a6: 7986 clear.d $r9
> }
> 800a8: 69a6 move.d $r9,$r10
> 800aa: 68e6 move.d $r8,$sp
> 800ac: 6e8e pop $r8
> 800ae: 3e0d jump [$sp+]
> The section .debug_aranges contains:
>
> Length: 28
> Version: 2
> Offset into .debug_info: 0
> Pointer Size: 4
> Segment Size: 0
>
> Address Length
> 00080074 60
>
> Contents of the .debug_pubnames section:
>
> Length: 39
> Version: 2
> Offset into .debug_info section: 0
> Size of area in .debug_info section: 105
>
> Offset Name
> 37 bar
> 56 foo
> 75 main
>
> The section .debug_info contains:
>
> Compilation Unit @ 0:
> Length: 101
> Version: 2
> Abbrev Offset: 0
> Pointer Size: 4
> <0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
> DW_AT_stmt_list : 0
> DW_AT_high_pc : 0x800b0 524464
> DW_AT_low_pc : 0x80074 524404
> DW_AT_name : (indirect string, offset: 0x34): test.c
> DW_AT_comp_dir : (indirect string, offset: 0x0): /home/orjanf
> DW_AT_producer : (indirect string, offset: 0xd): GNU C 3.2.1 Axis release R55/1.55
> DW_AT_language : 1 (ANSI C)
> <1><25>: Abbrev Number: 2 (DW_TAG_subprogram)
> DW_AT_external : 1
> DW_AT_name : bar
> DW_AT_decl_file : 1
> DW_AT_decl_line : 1
> DW_AT_prototyped : 1
> DW_AT_low_pc : 0x80074 524404
> DW_AT_high_pc : 0x80080 524416
> DW_AT_frame_base : 1 byte block: 58 (DW_OP_reg8; )
> <1><38>: Abbrev Number: 2 (DW_TAG_subprogram)
> DW_AT_external : 1
> DW_AT_name : foo
> DW_AT_decl_file : 1
> DW_AT_decl_line : 3
> DW_AT_prototyped : 1
> DW_AT_low_pc : 0x80080 524416
> DW_AT_high_pc : 0x80096 524438
> DW_AT_frame_base : 1 byte block: 58 (DW_OP_reg8; )
> <1><4b>: Abbrev Number: 3 (DW_TAG_subprogram)
> DW_AT_external : 1
> DW_AT_name : (indirect string, offset: 0x2f): main
> DW_AT_decl_file : 1
> DW_AT_decl_line : 7
> DW_AT_type : <61>
> DW_AT_low_pc : 0x80096 524438
> DW_AT_high_pc : 0x800b0 524464
> DW_AT_frame_base : 1 byte block: 58 (DW_OP_reg8; )
> <1><61>: Abbrev Number: 4 (DW_TAG_base_type)
> DW_AT_name : int
> DW_AT_byte_size : 4
> DW_AT_encoding : 5 (signed)
>
> Contents of the .debug_abbrev section:
>
> Number TAG
> 1 DW_TAG_compile_unit [has children]
> DW_AT_stmt_list DW_FORM_data4
> DW_AT_high_pc DW_FORM_addr
> DW_AT_low_pc DW_FORM_addr
> DW_AT_name DW_FORM_strp
> DW_AT_comp_dir DW_FORM_strp
> DW_AT_producer DW_FORM_strp
> DW_AT_language DW_FORM_data1
> 2 DW_TAG_subprogram [no children]
> DW_AT_external DW_FORM_flag
> DW_AT_name DW_FORM_string
> DW_AT_decl_file DW_FORM_data1
> DW_AT_decl_line DW_FORM_data1
> DW_AT_prototyped DW_FORM_flag
> DW_AT_low_pc DW_FORM_addr
> DW_AT_high_pc DW_FORM_addr
> DW_AT_frame_base DW_FORM_block1
> 3 DW_TAG_subprogram [no children]
> DW_AT_external DW_FORM_flag
> DW_AT_name DW_FORM_strp
> DW_AT_decl_file DW_FORM_data1
> DW_AT_decl_line DW_FORM_data1
> DW_AT_type DW_FORM_ref4
> DW_AT_low_pc DW_FORM_addr
> DW_AT_high_pc DW_FORM_addr
> DW_AT_frame_base DW_FORM_block1
> 4 DW_TAG_base_type [no children]
> DW_AT_name DW_FORM_string
> DW_AT_byte_size DW_FORM_data1
> DW_AT_encoding DW_FORM_data1
>
>
> Dump of debug contents of section .debug_line:
>
> Length: 52
> DWARF Version: 2
> Prologue Length: 26
> Minimum Instruction Length: 2
> Initial value of 'is_stmt': 1
> Line Base: -5
> Line Range: 14
> Opcode Base: 10
>
> Opcodes:
> Opcode 1 has 0 args
> Opcode 2 has 1 args
> Opcode 3 has 1 args
> Opcode 4 has 1 args
> Opcode 5 has 1 args
> Opcode 6 has 0 args
> Opcode 7 has 0 args
> Opcode 8 has 0 args
> Opcode 9 has 1 args
>
> The Directory Table is empty.
>
> The File Name Table:
> Entry Dir Time Size Name
> 1 0 0 0 test.c
>
> Line Number Statements:
> Extended opcode 2: set Address to 0x80074
> Special opcode 5: advance Address by 0 to 0x80074 and Line by 0 to 1
> Special opcode 91: advance Address by 12 to 0x80080 and Line by 2 to 3
> Special opcode 76: advance Address by 10 to 0x8008a and Line by 1 to 4
> Special opcode 48: advance Address by 6 to 0x80090 and Line by 1 to 5
> Special opcode 49: advance Address by 6 to 0x80096 and Line by 2 to 7
> Special opcode 76: advance Address by 10 to 0x800a0 and Line by 1 to 8
> Special opcode 48: advance Address by 6 to 0x800a6 and Line by 1 to 9
> Special opcode 20: advance Address by 2 to 0x800a8 and Line by 1 to 10
> Advance PC by 8 to 800b0
> Extended opcode 1: End of Sequence
>
>
> The section .debug_frame contains:
>
> 00000000 0000000c ffffffff CIE
> Version: 1
> Augmentation: ""
> Code alignment factor: 1
> Data alignment factor: -1
> Return address column: 16
>
> DW_CFA_def_cfa: r14 ofs 0
>
> 00000010 00000014 00000000 FDE cie=00000000 pc=00080074..00080080
> DW_CFA_advance_loc: 0 to 00080074
> DW_CFA_def_cfa: r8 ofs 4
> DW_CFA_offset: r8 at cfa-4
> DW_CFA_nop
> DW_CFA_nop
>
> 00000028 00000014 00000000 FDE cie=00000000 pc=00080080..00080096
> DW_CFA_advance_loc: 0 to 00080080
> DW_CFA_def_cfa: r8 ofs 8
> DW_CFA_offset: r16 at cfa-4
> DW_CFA_offset: r8 at cfa-8
>
> 00000040 00000014 00000000 FDE cie=00000000 pc=00080096..000800b0
> DW_CFA_advance_loc: 0 to 00080096
> DW_CFA_def_cfa: r8 ofs 8
> DW_CFA_offset: r16 at cfa-4
> DW_CFA_offset: r8 at cfa-8
>
> Contents of the .debug_str section:
>
> 0x00000000 2f686f6d 652f6f72 6a616e66 00474e55 /home/orjanf.GNU
> 0x00000010 20432033 2e322e31 20417869 73207265 C 3.2.1 Axis re
> 0x00000020 6c656173 65205235 352f312e 3535006d lease R55/1.55.m
> 0x00000030 61696e00 74657374 2e6300 ain.test.c.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-12 10:23 ` Orjan Friberg
` (2 preceding siblings ...)
2004-03-19 0:09 ` Orjan Friberg
@ 2004-03-19 0:09 ` Orjan Friberg
2004-03-12 15:38 ` Orjan Friberg
3 siblings, 1 reply; 36+ messages in thread
From: Orjan Friberg @ 2004-03-19 0:09 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
Orjan Friberg wrote:
> Daniel Jacobowitz wrote:
>
>>
>> The beauty of using the CFI data is that it _is_ supposed to work in
>> the prologue. It sounds like the CFI is wrong. Could you post both
>> assembly and CFI data for the same testcase? I don't know CRIS
>> assembly but I imagine I can interpret it well enough to see what's
>> going on.
Out of curiosity, I had a look at the calls to execute_cfa_program
(where the current state of the registers seems to be built from the
dwarf2 information). The second call to execute_cfa_program is preceded
by the comment:
/* Then decode the insns in the FDE up to our target PC. */
When we get into execute_cfa_program we're stopped at the first
instruction in foo, and the pc variable in execute_cfa_program is set to
that value also. Nevertheless we parse *all* the information in that FDE:
> 00000028 00000014 00000000 FDE cie=00000000 pc=00080080..00080096
> DW_CFA_advance_loc: 0 to 00080080
> DW_CFA_def_cfa: r8 ofs 8
> DW_CFA_offset: r16 at cfa-4
> DW_CFA_offset: r8 at cfa-8
So, not only do we incorrectly conclude that the SRP is located on the
stack, but that the frame pointer (r8) is also (though neither of those
have actually been pushed yet). Comparing with the example in Appendix
5 of the dwarf2 spec I get the impression that some DW_CFA_advance_loc
are missing, but now is probably a good time for me to stop guessing ;-) .
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-11 17:05 ` Andrew Cagney
@ 2004-03-19 0:09 ` Orjan Friberg
2004-03-12 12:00 ` Orjan Friberg
2004-03-19 0:09 ` Andrew Cagney
1 sibling, 1 reply; 36+ messages in thread
From: Orjan Friberg @ 2004-03-19 0:09 UTC (permalink / raw)
To: Andrew Cagney; +Cc: Daniel Jacobowitz, gdb-patches
Andrew Cagney wrote:
>
> Does this:
>
> /* NOTE: cagney/2003-09-05: CFI should specify the disposition
> of all debug info registers. If it doesn't, complain (but
> not too loudly). It turns out that GCC assumes that an
> unspecified register implies "same value" when CFI (draft
> 7) specifies nothing at all. Such a register could equally
> be interpreted as "undefined". Also note that this check
> isn't sufficient; it only checks that all registers in the
> range [0 .. max column] are specified, and won't detect
> problems when a debug info register falls outside of the
> table. We need a way of iterating through all the valid
> DWARF2 register numbers. */
> if (fs->regs.reg[column].how == DWARF2_FRAME_REG_UNSPECIFIED)
> complaint (&symfile_complaints,
> "Incomplete CFI data; unspecified registers at 0x%s",
> paddr (fs->pc));
> else
> cache->reg[regnum] = fs->regs.reg[column];
>
> sound like your problem? It's possible to specify initial values of
> such registers with:
I do get that complaint, and it seems a lot of registers are set to
DWARF2_FRAME_REG_UNSPECIFIED.
> /* Set the architecture-specific register state initialization
> function for GDBARCH to INIT_REG. */
>
> extern void dwarf2_frame_set_init_reg (struct gdbarch *gdbarch,
> void (*init_reg) (struct gdbarch
> *, int,
> struct
> dwarf2_frame_state_reg *));
Thanks for the tip, I hadn't seen that. Reading the s390 implementation
of dwarf2_frame_init_reg I get the impression that that information
should have been there from the beginning (emitted by gcc that is) since
it seems to be ABI/calling convention related. But I'll try and
implement something similar.
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-10 16:59 ` Daniel Jacobowitz
2004-03-19 0:09 ` Daniel Jacobowitz
@ 2004-03-19 0:09 ` Orjan Friberg
2004-03-11 14:09 ` Orjan Friberg
2004-03-11 15:55 ` Orjan Friberg
1 sibling, 2 replies; 36+ messages in thread
From: Orjan Friberg @ 2004-03-19 0:09 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
Daniel Jacobowitz wrote:
>
> Well, it sounds like the return address is being unwound incorrectly.
> You may want to take a look at the CFI data by hand, and then compare
> with dwarf2_frame_prev_register. I can't quite imagine how you'd get
> the one-instruction-early behavior, though :)
(The "one-instruction-early" description of the breakpoint setting was
incorrect - that breakpoint was actually the "break main" breakpoint.
Thanks for noticing.)
The test program is just:
void foo(void) {}
int main ()
{
foo();
return 0;
}
Here's what happens when I do "next" over the call to foo():
dwarf2_frame_prev_register gets called for register 15 (PC). The switch
on cache->reg[regnum].how leads to DWARF2_FRAME_REG_SAVED_REG, where
cache->reg[regnum].loc.reg says the PC is located in register 16, so we
unwind register 16 from the next frame, which is definitely wrong
(register 16 is a 8-bit zero register). Changing 16 to 27 (SRP, where
the PC is saved) makes "next" work in this simple case.
I did a readelf -w on the binary (below), and looked at the
.debug_frame-section (hoping that's what you meant by "look at the CFI
data by hand"), and though my understanding of this is limited I get the
impression that the dwarf2 CFI for CRIS is wrong (but that the dwarf2
frame unwinder does the right thing). "Return address column" says 16,
and for main (where the SRP is pushed on the stack) it says
"DW_CFA_offset: r16 at cfa-4".
I checked section 6.4.1 in the dwarf2 standard, but I couldn't confirm
my suspicions since some of the fields mentioned weren't present in the
readelf output (return_address_register for example).
00000010 0000000c ffffffff CIE
Version: 1
Augmentation: ""
Code alignment factor: 1
Data alignment factor: -1
Return address column: 16
DW_CFA_def_cfa: r14 ofs 0
00000020 00000014 00000010 FDE cie=00000010 pc=000802e4..000802f0
DW_CFA_advance_loc: 0 to 000802e4
DW_CFA_def_cfa: r8 ofs 4
DW_CFA_offset: r8 at cfa-4
DW_CFA_nop
DW_CFA_nop
00000038 00000014 00000010 FDE cie=00000010 pc=000802f0..0008030a
DW_CFA_advance_loc: 0 to 000802f0
DW_CFA_def_cfa: r8 ofs 8
DW_CFA_offset: r16 at cfa-4
DW_CFA_offset: r8 at cfa-8
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-16 23:38 ` Hans-Peter Nilsson
2004-03-16 23:58 ` Daniel Jacobowitz
@ 2004-03-19 0:09 ` Hans-Peter Nilsson
1 sibling, 0 replies; 36+ messages in thread
From: Hans-Peter Nilsson @ 2004-03-19 0:09 UTC (permalink / raw)
To: drow; +Cc: hans-peter.nilsson, orjan.friberg, gdb-patches
> Date: Tue, 16 Mar 2004 17:27:09 -0500
> From: Daniel Jacobowitz <drow@false.org>
> On Tue, Mar 16, 2004 at 09:50:28PM +0100, Hans-Peter Nilsson wrote:
> > > Date: Tue, 16 Mar 2004 14:13:01 -0500
> > > From: Daniel Jacobowitz <drow@false.org>
> > > On Tue, Mar 16, 2004 at 05:26:16PM +0100, Orjan Friberg wrote:
> > > > Would emitting that label *after* the prologue be an option (i.e.
> > > > leaving us without dwarf2 information while still in the prologue)?
> > > Nope. Then when you step into the prologue (i.e. "step over") unwind
> > > information will be incorrect.
> > Is that the whole effect, incorrectness for gdb usage *inside*
> > the prologue?
>
> Probably yes. So backtraces will not be affected but every bit of
> running is likely to misbehave.
*When* do things go wrong? Is it all gdb run-type commands all
the time, or is it just when (manually) looking around after
(manually) doing "stepi" into the prologue but not out of it?
Something else? Just curious in case you have the answer at
hand; I'll try and pursue splitting up EH & debug info.
> > Yeah, there should be a way to emit
> > different dwarf2 EH from that for debug. Hmm, maybe it would
> > work to just withholding all advance_loc codes except the last
> > one for for_eh && !flag_asynchronous_unwind_tables in
> > gcc/dwarf2out.c (sort of). And a target-specific hook for
> > "advancing loc", which could use the new gas dwarf2 directives
> > so it's not always advance_loc4. Getting off-topic here...
>
> Yeah, that may be the best way to solve this - emit more info in the
> .debug_frame than in .eh_frame, if you aren't supporting asynchronous
> unwinding. Like throwing from signal handlers taken during prologues,
> et cetera.
Yeah, flag_asynchronous_unwind_tables means all that. ISTR Java
and Ada uses that, or should.
> GDB gets _very_ cranky when unwind information is specified but not
> correct.
Opportunities for improvements in the failure mode here? ;-)
brgds, H-P
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-12 10:23 ` Orjan Friberg
2004-03-19 0:09 ` Daniel Jacobowitz
2004-03-19 0:09 ` Orjan Friberg
@ 2004-03-19 0:09 ` Orjan Friberg
2004-03-12 13:50 ` Orjan Friberg
2004-03-19 0:09 ` Orjan Friberg
3 siblings, 1 reply; 36+ messages in thread
From: Orjan Friberg @ 2004-03-19 0:09 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
Orjan Friberg wrote:
> Ugh, I had totally missed that (i.e. I don't even have a CRIS-specific
> DWARF2_REG_TO_REGNUM). Looking at the other targets' implementations I
> don't understand where they got the dwarf2 register mapping from (though
> amd64-tdep.c mentions System V psABI), and the dwarf2 spec says in
> "2.4.2 Register Name Operators" it should be in the architecture's ABI
> spec. I'll go bug my compiler guy, or go look in gcc myself.
Too trigger happy on the send button... The mn10300 told me where to
find it (gcc/config/cris/cris.h). It seems only the SRP needs special
handling (besides the ones that aren't mapped at all).
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-12 10:23 ` Orjan Friberg
2004-03-19 0:09 ` Daniel Jacobowitz
@ 2004-03-19 0:09 ` Orjan Friberg
2004-03-19 0:09 ` Orjan Friberg
2004-03-19 0:09 ` Orjan Friberg
3 siblings, 0 replies; 36+ messages in thread
From: Orjan Friberg @ 2004-03-19 0:09 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
[-- Attachment #1: Type: text/plain, Size: 1192 bytes --]
Daniel Jacobowitz wrote:
>
> The beauty of using the CFI data is that it _is_ supposed to work in
> the prologue. It sounds like the CFI is wrong. Could you post both
> assembly and CFI data for the same testcase? I don't know CRIS
> assembly but I imagine I can interpret it well enough to see what's
> going on.
I have attached the test program, dissassembly (objdump -d -S) and the
dwarf2 info (readelf -w). (Crash course in CRIS assembly, if at all
needed: r8 holds the frame pointer and srp holds the return address,
pushed only in non-leaf functions.)
> It also sounds like your DWARF2_REG_TO_REGNUM may need work, if the
> unwinder thinks r16 is the return address column and GDB thinks it's an
> 8-bit register.
Ugh, I had totally missed that (i.e. I don't even have a CRIS-specific
DWARF2_REG_TO_REGNUM). Looking at the other targets' implementations I
don't understand where they got the dwarf2 register mapping from (though
amd64-tdep.c mentions System V psABI), and the dwarf2 spec says in
"2.4.2 Register Name Operators" it should be in the architecture's ABI
spec. I'll go bug my compiler guy, or go look in gcc myself.
--
Orjan Friberg
Axis Communications
[-- Attachment #2: test.c --]
[-- Type: text/x-csrc, Size: 84 bytes --]
void bar(void) {}
void foo(void)
{
bar();
}
int main ()
{
foo();
return 0;
}
[-- Attachment #3: disassembly --]
[-- Type: text/plain, Size: 1102 bytes --]
test: file format elf32-cris
Disassembly of section .text:
00080074 <bar>:
void bar(void) {}
80074: fce1 ee8f push $r8
80078: 6e86 move.d $sp,$r8
8007a: 68e6 move.d $r8,$sp
8007c: 7fb6 ret
8007e: 6e8e pop $r8
00080080 <foo>:
void foo(void)
{
80080: fce1 7ebe push $srp
80084: fce1 ee8f push $r8
80088: 6e86 move.d $sp,$r8
bar();
8008a: 3fbd 7400 0800 jsr 80074 <bar>
}
80090: 68e6 move.d $r8,$sp
80092: 6e8e pop $r8
80094: 3e0d jump [$sp+]
00080096 <main>:
int main ()
{
80096: fce1 7ebe push $srp
8009a: fce1 ee8f push $r8
8009e: 6e86 move.d $sp,$r8
foo();
800a0: 3fbd 8000 0800 jsr 80080 <foo>
return 0;
800a6: 7986 clear.d $r9
}
800a8: 69a6 move.d $r9,$r10
800aa: 68e6 move.d $r8,$sp
800ac: 6e8e pop $r8
800ae: 3e0d jump [$sp+]
[-- Attachment #4: dwarf2info --]
[-- Type: text/plain, Size: 5843 bytes --]
The section .debug_aranges contains:
Length: 28
Version: 2
Offset into .debug_info: 0
Pointer Size: 4
Segment Size: 0
Address Length
00080074 60
Contents of the .debug_pubnames section:
Length: 39
Version: 2
Offset into .debug_info section: 0
Size of area in .debug_info section: 105
Offset Name
37 bar
56 foo
75 main
The section .debug_info contains:
Compilation Unit @ 0:
Length: 101
Version: 2
Abbrev Offset: 0
Pointer Size: 4
<0><b>: Abbrev Number: 1 (DW_TAG_compile_unit)
DW_AT_stmt_list : 0
DW_AT_high_pc : 0x800b0 524464
DW_AT_low_pc : 0x80074 524404
DW_AT_name : (indirect string, offset: 0x34): test.c
DW_AT_comp_dir : (indirect string, offset: 0x0): /home/orjanf
DW_AT_producer : (indirect string, offset: 0xd): GNU C 3.2.1 Axis release R55/1.55
DW_AT_language : 1 (ANSI C)
<1><25>: Abbrev Number: 2 (DW_TAG_subprogram)
DW_AT_external : 1
DW_AT_name : bar
DW_AT_decl_file : 1
DW_AT_decl_line : 1
DW_AT_prototyped : 1
DW_AT_low_pc : 0x80074 524404
DW_AT_high_pc : 0x80080 524416
DW_AT_frame_base : 1 byte block: 58 (DW_OP_reg8; )
<1><38>: Abbrev Number: 2 (DW_TAG_subprogram)
DW_AT_external : 1
DW_AT_name : foo
DW_AT_decl_file : 1
DW_AT_decl_line : 3
DW_AT_prototyped : 1
DW_AT_low_pc : 0x80080 524416
DW_AT_high_pc : 0x80096 524438
DW_AT_frame_base : 1 byte block: 58 (DW_OP_reg8; )
<1><4b>: Abbrev Number: 3 (DW_TAG_subprogram)
DW_AT_external : 1
DW_AT_name : (indirect string, offset: 0x2f): main
DW_AT_decl_file : 1
DW_AT_decl_line : 7
DW_AT_type : <61>
DW_AT_low_pc : 0x80096 524438
DW_AT_high_pc : 0x800b0 524464
DW_AT_frame_base : 1 byte block: 58 (DW_OP_reg8; )
<1><61>: Abbrev Number: 4 (DW_TAG_base_type)
DW_AT_name : int
DW_AT_byte_size : 4
DW_AT_encoding : 5 (signed)
Contents of the .debug_abbrev section:
Number TAG
1 DW_TAG_compile_unit [has children]
DW_AT_stmt_list DW_FORM_data4
DW_AT_high_pc DW_FORM_addr
DW_AT_low_pc DW_FORM_addr
DW_AT_name DW_FORM_strp
DW_AT_comp_dir DW_FORM_strp
DW_AT_producer DW_FORM_strp
DW_AT_language DW_FORM_data1
2 DW_TAG_subprogram [no children]
DW_AT_external DW_FORM_flag
DW_AT_name DW_FORM_string
DW_AT_decl_file DW_FORM_data1
DW_AT_decl_line DW_FORM_data1
DW_AT_prototyped DW_FORM_flag
DW_AT_low_pc DW_FORM_addr
DW_AT_high_pc DW_FORM_addr
DW_AT_frame_base DW_FORM_block1
3 DW_TAG_subprogram [no children]
DW_AT_external DW_FORM_flag
DW_AT_name DW_FORM_strp
DW_AT_decl_file DW_FORM_data1
DW_AT_decl_line DW_FORM_data1
DW_AT_type DW_FORM_ref4
DW_AT_low_pc DW_FORM_addr
DW_AT_high_pc DW_FORM_addr
DW_AT_frame_base DW_FORM_block1
4 DW_TAG_base_type [no children]
DW_AT_name DW_FORM_string
DW_AT_byte_size DW_FORM_data1
DW_AT_encoding DW_FORM_data1
Dump of debug contents of section .debug_line:
Length: 52
DWARF Version: 2
Prologue Length: 26
Minimum Instruction Length: 2
Initial value of 'is_stmt': 1
Line Base: -5
Line Range: 14
Opcode Base: 10
Opcodes:
Opcode 1 has 0 args
Opcode 2 has 1 args
Opcode 3 has 1 args
Opcode 4 has 1 args
Opcode 5 has 1 args
Opcode 6 has 0 args
Opcode 7 has 0 args
Opcode 8 has 0 args
Opcode 9 has 1 args
The Directory Table is empty.
The File Name Table:
Entry Dir Time Size Name
1 0 0 0 test.c
Line Number Statements:
Extended opcode 2: set Address to 0x80074
Special opcode 5: advance Address by 0 to 0x80074 and Line by 0 to 1
Special opcode 91: advance Address by 12 to 0x80080 and Line by 2 to 3
Special opcode 76: advance Address by 10 to 0x8008a and Line by 1 to 4
Special opcode 48: advance Address by 6 to 0x80090 and Line by 1 to 5
Special opcode 49: advance Address by 6 to 0x80096 and Line by 2 to 7
Special opcode 76: advance Address by 10 to 0x800a0 and Line by 1 to 8
Special opcode 48: advance Address by 6 to 0x800a6 and Line by 1 to 9
Special opcode 20: advance Address by 2 to 0x800a8 and Line by 1 to 10
Advance PC by 8 to 800b0
Extended opcode 1: End of Sequence
The section .debug_frame contains:
00000000 0000000c ffffffff CIE
Version: 1
Augmentation: ""
Code alignment factor: 1
Data alignment factor: -1
Return address column: 16
DW_CFA_def_cfa: r14 ofs 0
00000010 00000014 00000000 FDE cie=00000000 pc=00080074..00080080
DW_CFA_advance_loc: 0 to 00080074
DW_CFA_def_cfa: r8 ofs 4
DW_CFA_offset: r8 at cfa-4
DW_CFA_nop
DW_CFA_nop
00000028 00000014 00000000 FDE cie=00000000 pc=00080080..00080096
DW_CFA_advance_loc: 0 to 00080080
DW_CFA_def_cfa: r8 ofs 8
DW_CFA_offset: r16 at cfa-4
DW_CFA_offset: r8 at cfa-8
00000040 00000014 00000000 FDE cie=00000000 pc=00080096..000800b0
DW_CFA_advance_loc: 0 to 00080096
DW_CFA_def_cfa: r8 ofs 8
DW_CFA_offset: r16 at cfa-4
DW_CFA_offset: r8 at cfa-8
Contents of the .debug_str section:
0x00000000 2f686f6d 652f6f72 6a616e66 00474e55 /home/orjanf.GNU
0x00000010 20432033 2e322e31 20417869 73207265 C 3.2.1 Axis re
0x00000020 6c656173 65205235 352f312e 3535006d lease R55/1.55.m
0x00000030 61696e00 74657374 2e6300 ain.test.c.
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-11 15:55 ` Orjan Friberg
2004-03-11 17:05 ` Andrew Cagney
2004-03-11 17:11 ` Daniel Jacobowitz
@ 2004-03-19 0:09 ` Orjan Friberg
2 siblings, 0 replies; 36+ messages in thread
From: Orjan Friberg @ 2004-03-19 0:09 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
I don't know if this is related to the previous suggested problem (i.e.
the dwarf2 information being wrong), but I changed the test program
slightly to:
void bar(void) {}
void foo(void)
{
bar();
}
int main ()
{
foo();
return 0;
}
Now foo is no longer a leaf function, and thus saves the return address
on the stack in its prologue. Stepping over foo ("next" in main) causes
a breakpoint to be set at the first instruction in foo. After the
target is stopped at that instruction (which is where the return address
is pushed on the stack) dwarf2_frame_prev_register is called, which
thinks that the PC is saved on the stack (case
DWARF2_FRAME_REG_SAVED_OFFSET) and reads it from there. Obviously the
value it reads is wrong, since the return address hasn't been pushed yet.
What's wrong here? Is the dwarf2 debug information wrong, or should
dwarf2_frame_prev_register not have been called while still in the prologue?
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-15 10:19 ` Orjan Friberg
@ 2004-03-19 0:09 ` Orjan Friberg
0 siblings, 0 replies; 36+ messages in thread
From: Orjan Friberg @ 2004-03-19 0:09 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches
Daniel Jacobowitz wrote:
>
> I see that your GCC port uses textual prologues. As it happens, I just
> implemented dwarf generation for that mechanism (for Thumb), so I know
> how it's supposed to work. Here's your problem. First you have:
Daniel,
Thanks a lot for your help - I've forwarded it to the gcc CRIS maintainer.
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-16 20:51 ` Hans-Peter Nilsson
2004-03-16 22:27 ` Daniel Jacobowitz
@ 2004-03-19 0:09 ` Hans-Peter Nilsson
1 sibling, 0 replies; 36+ messages in thread
From: Hans-Peter Nilsson @ 2004-03-19 0:09 UTC (permalink / raw)
To: drow; +Cc: orjan.friberg, gdb-patches, hans-peter.nilsson
> Date: Tue, 16 Mar 2004 14:13:01 -0500
> From: Daniel Jacobowitz <drow@false.org>
Hi Dan.
> On Tue, Mar 16, 2004 at 05:26:16PM +0100, Orjan Friberg wrote:
> > Would emitting that label *after* the prologue be an option (i.e.
> > leaving us without dwarf2 information while still in the prologue)?
>
> Nope. Then when you step into the prologue (i.e. "step over") unwind
> information will be incorrect.
Is that the whole effect, incorrectness for gdb usage *inside*
the prologue?
> I recommend taking a look at the patch where I implemented this for
> Thumb, or at the m68k implementation.
I know *how* to do it, I just want to prod a little if there's a
way to avoid dwarf2 info (specifically advance_loc directives)
not necessary for EH unwinding and still have it working for gdb
modulo stepping inside the prologue. It worked fine until gdb
started to use dwarf2 too. :-)
As you know, the same info ends up in the EH unwind info as
well, and we don't want that to be larger than absolutely
necessary. (And as I suppose you *also* know, mentioned for the
record, "disk is cheap" is definitely not true when the disk is
solid-state memory.) Yeah, there should be a way to emit
different dwarf2 EH from that for debug. Hmm, maybe it would
work to just withholding all advance_loc codes except the last
one for for_eh && !flag_asynchronous_unwind_tables in
gcc/dwarf2out.c (sort of). And a target-specific hook for
"advancing loc", which could use the new gas dwarf2 directives
so it's not always advance_loc4. Getting off-topic here...
brgds, H-P
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-16 16:26 ` Orjan Friberg
2004-03-16 19:13 ` Daniel Jacobowitz
@ 2004-03-19 0:09 ` Orjan Friberg
1 sibling, 0 replies; 36+ messages in thread
From: Orjan Friberg @ 2004-03-19 0:09 UTC (permalink / raw)
To: Daniel Jacobowitz; +Cc: gdb-patches, Hans-Peter Nilsson
Daniel Jacobowitz wrote:
>
> I see that your GCC port uses textual prologues. As it happens, I just
> implemented dwarf generation for that mechanism (for Thumb), so I know
> how it's supposed to work. Here's your problem. First you have:
>
> /* FIXME: Slightly redundant calculation, as we do the same in
> pieces below. This offset must be the total adjustment of the
> stack-pointer. We can then def_cfa call at the end of this
> function with the current implementation of execute_cfa_insn, but
> that wouldn't really be clean. */
>
> cfa_label = dwarf2out_cfi_label ();
> dwarf2out_def_cfa (cfa_label, cfa_reg, cfa_offset);
>
> but that label is at the beginning of the function, so this is
> incorrect. That's not what the CFA is at the beginning of the
> function.
Would emitting that label *after* the prologue be an option (i.e.
leaving us without dwarf2 information while still in the prologue)?
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-10 16:59 ` Daniel Jacobowitz
@ 2004-03-19 0:09 ` Daniel Jacobowitz
2004-03-19 0:09 ` Orjan Friberg
1 sibling, 0 replies; 36+ messages in thread
From: Daniel Jacobowitz @ 2004-03-19 0:09 UTC (permalink / raw)
To: Orjan Friberg; +Cc: gdb-patches
On Wed, Mar 10, 2004 at 05:53:50PM +0100, Orjan Friberg wrote:
> After getting the CRIS port into shape without the dwarf2 frame sniffer,
> I hooked it in and found that basic stuff like next over a function call
> no longer works. (More specifically, after stepping into the function,
> gdb sets the breakpoint on the jump instruction itself, rather than at
> the instruction after.)
>
> I do get a complaint "During symbol reading, Incomplete CFI data;
> unspecified registers at 0x000802f6." already by the time I get to
> main(), where 802f6 is the first address in main(), which is where the
> subroutine pointer is pushed. Although there is a comment in
> dwarf2-frame.c explaining the complaint, I'm not sure how seriously I
> should take it.
That shouldn't be the problem.
> Thanks for any idea on what might be the cause or where to start digging.
Well, it sounds like the return address is being unwound incorrectly.
You may want to take a look at the CFI data by hand, and then compare
with dwarf2_frame_prev_register. I can't quite imagine how you'd get
the one-instruction-early behavior, though :)
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-16 23:58 ` Daniel Jacobowitz
@ 2004-03-19 0:09 ` Daniel Jacobowitz
0 siblings, 0 replies; 36+ messages in thread
From: Daniel Jacobowitz @ 2004-03-19 0:09 UTC (permalink / raw)
To: Hans-Peter Nilsson; +Cc: orjan.friberg, gdb-patches
On Wed, Mar 17, 2004 at 12:38:00AM +0100, Hans-Peter Nilsson wrote:
> > Date: Tue, 16 Mar 2004 17:27:09 -0500
> > From: Daniel Jacobowitz <drow@false.org>
>
> > On Tue, Mar 16, 2004 at 09:50:28PM +0100, Hans-Peter Nilsson wrote:
> > > > Date: Tue, 16 Mar 2004 14:13:01 -0500
> > > > From: Daniel Jacobowitz <drow@false.org>
> > > > On Tue, Mar 16, 2004 at 05:26:16PM +0100, Orjan Friberg wrote:
> > > > > Would emitting that label *after* the prologue be an option (i.e.
> > > > > leaving us without dwarf2 information while still in the prologue)?
> > > > Nope. Then when you step into the prologue (i.e. "step over") unwind
> > > > information will be incorrect.
> > > Is that the whole effect, incorrectness for gdb usage *inside*
> > > the prologue?
> >
> > Probably yes. So backtraces will not be affected but every bit of
> > running is likely to misbehave.
>
> *When* do things go wrong? Is it all gdb run-type commands all
> the time, or is it just when (manually) looking around after
> (manually) doing "stepi" into the prologue but not out of it?
> Something else? Just curious in case you have the answer at
> hand; I'll try and pursue splitting up EH & debug info.
When you use "next", at a function call, GDB will step - then after
that instruction, it will try to find the frame ID. And then it will
unwind to find the caller's frame ID, and step or breakpoint/continue
until we get back there. So you've lost if you don't have the ability
to unwind at the first instruction.
Same if you "step" over something you don't have debug info for.
I'm sure there are more things that will go wrong; I don't know how
much.
>
> > > Yeah, there should be a way to emit
> > > different dwarf2 EH from that for debug. Hmm, maybe it would
> > > work to just withholding all advance_loc codes except the last
> > > one for for_eh && !flag_asynchronous_unwind_tables in
> > > gcc/dwarf2out.c (sort of). And a target-specific hook for
> > > "advancing loc", which could use the new gas dwarf2 directives
> > > so it's not always advance_loc4. Getting off-topic here...
> >
> > Yeah, that may be the best way to solve this - emit more info in the
> > .debug_frame than in .eh_frame, if you aren't supporting asynchronous
> > unwinding. Like throwing from signal handlers taken during prologues,
> > et cetera.
>
> Yeah, flag_asynchronous_unwind_tables means all that. ISTR Java
> and Ada uses that, or should.
>
> > GDB gets _very_ cranky when unwind information is specified but not
> > correct.
>
> Opportunities for improvements in the failure mode here? ;-)
Not really. You have unwind info; we have to either trust it, or not.
It's not failing to unwind, it's unwinding and providing incorrect
information...
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-11 17:11 ` Daniel Jacobowitz
2004-03-12 10:23 ` Orjan Friberg
@ 2004-03-19 0:09 ` Daniel Jacobowitz
1 sibling, 0 replies; 36+ messages in thread
From: Daniel Jacobowitz @ 2004-03-19 0:09 UTC (permalink / raw)
To: Orjan Friberg; +Cc: gdb-patches
On Thu, Mar 11, 2004 at 04:55:04PM +0100, Orjan Friberg wrote:
> I don't know if this is related to the previous suggested problem (i.e.
> the dwarf2 information being wrong), but I changed the test program
> slightly to:
>
> void bar(void) {}
> void foo(void)
> {
> bar();
> }
> int main ()
> {
> foo();
> return 0;
> }
>
> Now foo is no longer a leaf function, and thus saves the return address
> on the stack in its prologue. Stepping over foo ("next" in main) causes
> a breakpoint to be set at the first instruction in foo. After the
> target is stopped at that instruction (which is where the return address
> is pushed on the stack) dwarf2_frame_prev_register is called, which
> thinks that the PC is saved on the stack (case
> DWARF2_FRAME_REG_SAVED_OFFSET) and reads it from there. Obviously the
> value it reads is wrong, since the return address hasn't been pushed yet.
>
> What's wrong here? Is the dwarf2 debug information wrong, or should
> dwarf2_frame_prev_register not have been called while still in the prologue?
The beauty of using the CFI data is that it _is_ supposed to work in
the prologue. It sounds like the CFI is wrong. Could you post both
assembly and CFI data for the same testcase? I don't know CRIS
assembly but I imagine I can interpret it well enough to see what's
going on.
It also sounds like your DWARF2_REG_TO_REGNUM may need work, if the
unwinder thinks r16 is the return address column and GDB thinks it's an
8-bit register.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-16 22:27 ` Daniel Jacobowitz
2004-03-16 23:38 ` Hans-Peter Nilsson
@ 2004-03-19 0:09 ` Daniel Jacobowitz
1 sibling, 0 replies; 36+ messages in thread
From: Daniel Jacobowitz @ 2004-03-19 0:09 UTC (permalink / raw)
To: Hans-Peter Nilsson; +Cc: orjan.friberg, gdb-patches
On Tue, Mar 16, 2004 at 09:50:28PM +0100, Hans-Peter Nilsson wrote:
> > Date: Tue, 16 Mar 2004 14:13:01 -0500
> > From: Daniel Jacobowitz <drow@false.org>
>
> Hi Dan.
>
> > On Tue, Mar 16, 2004 at 05:26:16PM +0100, Orjan Friberg wrote:
> > > Would emitting that label *after* the prologue be an option (i.e.
> > > leaving us without dwarf2 information while still in the prologue)?
> >
> > Nope. Then when you step into the prologue (i.e. "step over") unwind
> > information will be incorrect.
>
> Is that the whole effect, incorrectness for gdb usage *inside*
> the prologue?
Probably yes. So backtraces will not be affected but every bit of
running is likely to misbehave.
> > I recommend taking a look at the patch where I implemented this for
> > Thumb, or at the m68k implementation.
>
> I know *how* to do it, I just want to prod a little if there's a
> way to avoid dwarf2 info (specifically advance_loc directives)
> not necessary for EH unwinding and still have it working for gdb
> modulo stepping inside the prologue. It worked fine until gdb
> started to use dwarf2 too. :-)
>
> As you know, the same info ends up in the EH unwind info as
> well, and we don't want that to be larger than absolutely
> necessary. (And as I suppose you *also* know, mentioned for the
> record, "disk is cheap" is definitely not true when the disk is
> solid-state memory.) Yeah, there should be a way to emit
> different dwarf2 EH from that for debug. Hmm, maybe it would
> work to just withholding all advance_loc codes except the last
> one for for_eh && !flag_asynchronous_unwind_tables in
> gcc/dwarf2out.c (sort of). And a target-specific hook for
> "advancing loc", which could use the new gas dwarf2 directives
> so it's not always advance_loc4. Getting off-topic here...
Yeah, that may be the best way to solve this - emit more info in the
.debug_frame than in .eh_frame, if you aren't supporting asynchronous
unwinding. Like throwing from signal handlers taken during prologues,
et cetera.
GDB gets _very_ cranky when unwind information is specified but not
correct.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-16 19:13 ` Daniel Jacobowitz
2004-03-16 20:51 ` Hans-Peter Nilsson
@ 2004-03-19 0:09 ` Daniel Jacobowitz
1 sibling, 0 replies; 36+ messages in thread
From: Daniel Jacobowitz @ 2004-03-19 0:09 UTC (permalink / raw)
To: Orjan Friberg; +Cc: gdb-patches, Hans-Peter Nilsson
On Tue, Mar 16, 2004 at 05:26:16PM +0100, Orjan Friberg wrote:
> Daniel Jacobowitz wrote:
> >
> >I see that your GCC port uses textual prologues. As it happens, I just
> >implemented dwarf generation for that mechanism (for Thumb), so I know
> >how it's supposed to work. Here's your problem. First you have:
> >
> > /* FIXME: Slightly redundant calculation, as we do the same in
> > pieces below. This offset must be the total adjustment of the
> > stack-pointer. We can then def_cfa call at the end of this
> > function with the current implementation of execute_cfa_insn, but
> > that wouldn't really be clean. */
> >
> > cfa_label = dwarf2out_cfi_label ();
> > dwarf2out_def_cfa (cfa_label, cfa_reg, cfa_offset);
> >
> >but that label is at the beginning of the function, so this is
> >incorrect. That's not what the CFA is at the beginning of the
> >function.
>
> Would emitting that label *after* the prologue be an option (i.e.
> leaving us without dwarf2 information while still in the prologue)?
Nope. Then when you step into the prologue (i.e. "step over") unwind
information will be incorrect.
I recommend taking a look at the patch where I implemented this for
Thumb, or at the m68k implementation.
--
Daniel Jacobowitz
MontaVista Software Debian GNU/Linux Developer
^ permalink raw reply [flat|nested] 36+ messages in thread
* Re: [CRIS] dwarf2 frame sniffer problem?
2004-03-11 17:05 ` Andrew Cagney
2004-03-19 0:09 ` Orjan Friberg
@ 2004-03-19 0:09 ` Andrew Cagney
1 sibling, 0 replies; 36+ messages in thread
From: Andrew Cagney @ 2004-03-19 0:09 UTC (permalink / raw)
To: Orjan Friberg; +Cc: Daniel Jacobowitz, gdb-patches
> I don't know if this is related to the previous suggested problem (i.e. the dwarf2 information being wrong), but I changed the test program slightly to:
>
> void bar(void) {}
> void foo(void)
> {
> bar();
> }
> int main ()
> {
> foo();
> return 0;
> }
>
> Now foo is no longer a leaf function, and thus saves the return address on the stack in its prologue. Stepping over foo ("next" in main) causes a breakpoint to be set at the first instruction in foo. After the target is stopped at that instruction (which is where the return address is pushed on the stack) dwarf2_frame_prev_register is called, which thinks that the PC is saved on the stack (case DWARF2_FRAME_REG_SAVED_OFFSET) and reads it from there. Obviously the value it reads is wrong, since the return address hasn't been pushed yet.
>
> What's wrong here? Is the dwarf2 debug information wrong, or should dwarf2_frame_prev_register not have been called while still in the prologue?
Does this:
/* NOTE: cagney/2003-09-05: CFI should specify the disposition
of all debug info registers. If it doesn't, complain (but
not too loudly). It turns out that GCC assumes that an
unspecified register implies "same value" when CFI (draft
7) specifies nothing at all. Such a register could equally
be interpreted as "undefined". Also note that this check
isn't sufficient; it only checks that all registers in the
range [0 .. max column] are specified, and won't detect
problems when a debug info register falls outside of the
table. We need a way of iterating through all the valid
DWARF2 register numbers. */
if (fs->regs.reg[column].how == DWARF2_FRAME_REG_UNSPECIFIED)
complaint (&symfile_complaints,
"Incomplete CFI data; unspecified registers at 0x%s",
paddr (fs->pc));
else
cache->reg[regnum] = fs->regs.reg[column];
sound like your problem? It's possible to specify initial values of
such registers with:
/* Set the architecture-specific register state initialization
function for GDBARCH to INIT_REG. */
extern void dwarf2_frame_set_init_reg (struct gdbarch *gdbarch,
void (*init_reg) (struct gdbarch
*, int,
struct
dwarf2_frame_state_reg *));
Andrew
^ permalink raw reply [flat|nested] 36+ messages in thread
* [CRIS] dwarf2 frame sniffer problem?
2004-03-10 16:53 [CRIS] dwarf2 frame sniffer problem? Orjan Friberg
2004-03-10 16:59 ` Daniel Jacobowitz
@ 2004-03-19 0:09 ` Orjan Friberg
1 sibling, 0 replies; 36+ messages in thread
From: Orjan Friberg @ 2004-03-19 0:09 UTC (permalink / raw)
To: gdb-patches
After getting the CRIS port into shape without the dwarf2 frame sniffer,
I hooked it in and found that basic stuff like next over a function call
no longer works. (More specifically, after stepping into the function,
gdb sets the breakpoint on the jump instruction itself, rather than at
the instruction after.)
I do get a complaint "During symbol reading, Incomplete CFI data;
unspecified registers at 0x000802f6." already by the time I get to
main(), where 802f6 is the first address in main(), which is where the
subroutine pointer is pushed. Although there is a comment in
dwarf2-frame.c explaining the complaint, I'm not sure how seriously I
should take it.
Thanks for any idea on what might be the cause or where to start digging.
--
Orjan Friberg
Axis Communications
^ permalink raw reply [flat|nested] 36+ messages in thread
end of thread, other threads:[~2004-03-16 23:58 UTC | newest]
Thread overview: 36+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-03-10 16:53 [CRIS] dwarf2 frame sniffer problem? Orjan Friberg
2004-03-10 16:59 ` Daniel Jacobowitz
2004-03-19 0:09 ` Daniel Jacobowitz
2004-03-19 0:09 ` Orjan Friberg
2004-03-11 14:09 ` Orjan Friberg
2004-03-11 15:55 ` Orjan Friberg
2004-03-11 17:05 ` Andrew Cagney
2004-03-19 0:09 ` Orjan Friberg
2004-03-12 12:00 ` Orjan Friberg
2004-03-19 0:09 ` Andrew Cagney
2004-03-11 17:11 ` Daniel Jacobowitz
2004-03-12 10:23 ` Orjan Friberg
2004-03-19 0:09 ` Daniel Jacobowitz
2004-03-12 15:38 ` Daniel Jacobowitz
2004-03-15 10:19 ` Orjan Friberg
2004-03-19 0:09 ` Orjan Friberg
2004-03-16 16:26 ` Orjan Friberg
2004-03-16 19:13 ` Daniel Jacobowitz
2004-03-16 20:51 ` Hans-Peter Nilsson
2004-03-16 22:27 ` Daniel Jacobowitz
2004-03-16 23:38 ` Hans-Peter Nilsson
2004-03-16 23:58 ` Daniel Jacobowitz
2004-03-19 0:09 ` Daniel Jacobowitz
2004-03-19 0:09 ` Hans-Peter Nilsson
2004-03-19 0:09 ` Daniel Jacobowitz
2004-03-19 0:09 ` Hans-Peter Nilsson
2004-03-19 0:09 ` Daniel Jacobowitz
2004-03-19 0:09 ` Orjan Friberg
2004-03-19 0:09 ` Orjan Friberg
2004-03-19 0:09 ` Orjan Friberg
2004-03-12 13:50 ` Orjan Friberg
2004-03-19 0:09 ` Orjan Friberg
2004-03-12 15:38 ` Orjan Friberg
2004-03-19 0:09 ` Daniel Jacobowitz
2004-03-19 0:09 ` Orjan Friberg
2004-03-19 0:09 ` Orjan Friberg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox