|
View:
New views
11 Messages
—
Rating Filter:
Alert me
|
|
|
Preserving the argument spills for GDBDear all,
I've been working on handling the Debugging information for the use of GDB on my port. Though I definitely know that, when compiling in -O3, some information is lost and the debugger can't always have all the information, I'd like to at least keep the values of the arguments when doing a backtrace. Since my architecture uses register passing for arguments, relatively quickly this is lost since it is not stored on the stack. Therefore, I would like to, when doing a backtrace, have the argument information. I asked a few clarifications on the GDB mailing list and, it seems, that I need to copy the arguments on the stack (like what is done by default when using -O0). However, when compiling in -O3, the compiler of course removes these stores on the stack and relies solely (and justly so) on the input registers. I've reread the GCC internals and have been looking at anything regarding the stack but can't seem to figure this one out. How exactly do I explain to the compiler that I want to keep those spills to the stack for debugging purposes ? Thanks for your help, Jc |
|
|
Re: Preserving the argument spills for GDBI will try to add more details about my issue. Another way of putting this is :
For my architecture there is: - A certain number of input registers which allow calls without going on the stack - There is not automatically a frame pointer on the stack either What is needed, from the GCC side, to provide GDB with enough information to preserve the arguments that are passed and allow to see a backtrace and walk the stack. Do we need to change the ABI and store certain indispensable things on the stack for GDB ? I see very little documentation about this or questions, so I don't know exactly where to look to. Note: in O0 levels, the compiler does actually store the arguments on the stack and has a frame pointer, this gives GDB the possibility to do show the arguments passed to a function at a break point but not the backtrace. In O3, however, I don't even get the arguments correct. Thanks for any input, Jc On Tue, Nov 3, 2009 at 2:01 PM, Jean Christophe Beyler <jean.christophe.beyler@...> wrote: > Dear all, > > I've been working on handling the Debugging information for the use of > GDB on my port. Though I definitely know that, when compiling in -O3, > some information is lost and the debugger can't always have all the > information, I'd like to at least keep the values of the arguments > when doing a backtrace. Since my architecture uses register passing > for arguments, relatively quickly this is lost since it is not stored > on the stack. > > Therefore, I would like to, when doing a backtrace, have the argument > information. I asked a few clarifications on the GDB mailing list and, > it seems, that I need to copy the arguments on the stack (like what is > done by default when using -O0). However, when compiling in -O3, the > compiler of course removes these stores on the stack and relies solely > (and justly so) on the input registers. > > I've reread the GCC internals and have been looking at anything > regarding the stack but can't seem to figure this one out. How exactly > do I explain to the compiler that I want to keep those spills to the > stack for debugging purposes ? > > Thanks for your help, > Jc > |
|
|
Re: Preserving the argument spills for GDBJean Christophe Beyler <jean.christophe.beyler@...> writes:
> I've been working on handling the Debugging information for the use of > GDB on my port. Though I definitely know that, when compiling in -O3, > some information is lost and the debugger can't always have all the > information, I'd like to at least keep the values of the arguments > when doing a backtrace. Since my architecture uses register passing > for arguments, relatively quickly this is lost since it is not stored > on the stack. > > Therefore, I would like to, when doing a backtrace, have the argument > information. I asked a few clarifications on the GDB mailing list and, > it seems, that I need to copy the arguments on the stack (like what is > done by default when using -O0). However, when compiling in -O3, the > compiler of course removes these stores on the stack and relies solely > (and justly so) on the input registers. > > I've reread the GCC internals and have been looking at anything > regarding the stack but can't seem to figure this one out. How exactly > do I explain to the compiler that I want to keep those spills to the > stack for debugging purposes ? You can force your writes to the stack to not be removed by making them use UNSPEC_VOLATILE. You would write special define_insns for this. Not to miss the obvious, note that this will hurt optimization. However, if you need to have the argument values available for all backtraces, then I'm not sure what else to recommend. In general gcc will discard argument values that are not needed. Ian |
|
|
Re: Preserving the argument spills for GDB> You can force your writes to the stack to not be removed by making
> them use UNSPEC_VOLATILE. You would write special define_insns for > this. Is there an architecture port that has done this already ? > Not to miss the obvious, note that this will hurt optimization. > However, if you need to have the argument values available for all > backtraces, then I'm not sure what else to recommend. In general gcc > will discard argument values that are not needed. I know. Personally, I have not been advocating this but for the moment, we have been making a study at what would be needed and how bad it would be. However, I've been going through the first step : running GDB, setting a break-point and doing a continue to see what I get and try to get the information right for O3 too. In O0, I get: Breakpoint @@ 1, foo (a=4, b=3, c=2, d=1) at hello.c:10 In O3, I get: Breakpoint @@ 1, foo (a=Variable "a" is not available.) at hello.c:11 Now, I've been able to tell GCC to save those arguments exactly at the same address in O3 as it does in O0 (I hacked the varargs saving arguments code so that it would do the same thing for all functions). It seems that, in the O0 case, the Dwarf information is automatically propagated to say "The input register is now here", but when I do it in O3, I'm issuing the information in the same way. What am I exactly missing? Any ideas why GDB would not have enough information in this case? Thanks, Jean Christophe Beyler |
|
|
Re: Preserving the argument spills for GDBOn Wed, Nov 04, 2009 at 11:24:34AM -0500, Jean Christophe Beyler wrote:
> However, I've been going through the first step : running GDB, setting > a break-point and doing a continue to see what I get and try to get > the information right for O3 too. > > In O0, I get: > Breakpoint @@ 1, foo (a=4, b=3, c=2, d=1) at hello.c:10 > > In O3, I get: > Breakpoint @@ 1, foo (a=Variable "a" is not available.) at hello.c:11 > > It seems that, in the O0 case, the Dwarf information is automatically > propagated to say "The input register is now here", but when I do it > in O3, I'm issuing the information in the same way. > > What am I exactly missing? Any ideas why GDB would not have enough > information in this case? You should look at the DWARF information (readelf -wi) and see if the function parameters have DW_AT_location attributes. If they don't, then you need to ensure that they get generated. If they do, then perhaps they are wrong or GDB is not interpreting them correctly. (They get generated with optimization and interpreted correctly on other platforms that pass args in registers.) -Nathan |
|
|
Re: Preserving the argument spills for GDBJean Christophe Beyler <jean.christophe.beyler@...> writes:
>> You can force your writes to the stack to not be removed by making >> them use UNSPEC_VOLATILE. You would write special define_insns for >> this. > > Is there an architecture port that has done this already ? No, because, when given the choice, gcc prefers faster execution over more reliable debugging at high optimization levels. Ian |
|
|
Re: Preserving the argument spills for GDBYes I understand. I'm trying to give multiple options to the users in
order to either have this enabled or not actually. I'm running into one issue. In order for this to work, it would be better if I could keep the top of the frame and the stack pointer in two separate registers. This way, whatever happens, I know where to find the top of the frame. I have set HARD_FRAME_POINTER_REGNUM and I have, after I store the hard_frame_pointer on the stack and update the stack pointer generated : /* Update HARD_FRAME_POINTER_REGNUM */ insn = emit_move_insn (hard_frame_pointer_rtx, stack_pointer_rtx); RTX_FRAME_RELATED_P (insn) = 1; At the end of the function, I load back the hard_frame_pointer and set back the stack pointer. However, in O3, the compiler sometimes decides that my instruction is useless. For debugging purposes this is not good since I put the stack pointer and the return address in fixed places relative to this frame pointer and not the stack pointer (since the stack can move around depending on variable arguments, it's better to use that register). How can I force the prologue to keep this instruction. It is useless only in the case that there is no function call or no alloca. But I have a case where there is a function call and it is still removed. Any ideas ? Thank you very much for your input, Jc On Wed, Nov 4, 2009 at 11:45 AM, Ian Lance Taylor <iant@...> wrote: > Jean Christophe Beyler <jean.christophe.beyler@...> writes: > >>> You can force your writes to the stack to not be removed by making >>> them use UNSPEC_VOLATILE. You would write special define_insns for >>> this. >> >> Is there an architecture port that has done this already ? > > No, because, when given the choice, gcc prefers faster execution over > more reliable debugging at high optimization levels. > > Ian > |
|
|
Re: Preserving the argument spills for GDBJean Christophe Beyler <jean.christophe.beyler@...> writes:
> How can I force the prologue to keep this instruction. It is useless > only in the case that there is no function call or no alloca. But I > have a case where there is a function call and it is still removed. Make the hard frame pointer register a fixed register, or add it to EPILOGUE_USES. Ian |
|
|
Re: Preserving the argument spills for GDBI actually already did put it as a fixed register using the
FIXED_REGISTER macro. However, I have not yet tested the EPILOGUE_USES because it said that : "The stack and frame pointer are already assumed to be used as needed". My current port defines a different FRAME_POINTER_REGNUM from the HARD_FRAME_POINTER_REGNUM. I have this because before register allocation it is not possible to know the offset as it is said in the Internals. Basically, my code looks like this: move stack pointer down conditional trap on stack pointer store on stack the return address store on stack the frame pointer HARD_FRAME_POINTER_REGNUM (it's the old one so that we know where it started) mov HARD_FRAME_POINTER_REGNUM, stack_pointer ... Function code ... restore return address restore HARD_FRAME_POINTER_REGNUM mov stack_pointer, HARD_FRAME_POINTER_REGNUM This seemed like the simplest solution but it seems to be that, because I restore it in the epilogue, it considers the move as being useless since it doesn't realize it is needed by subsequent function calls in the function code. Thanks for any input, Jc On Mon, Nov 9, 2009 at 10:40 AM, Ian Lance Taylor <iant@...> wrote: > Jean Christophe Beyler <jean.christophe.beyler@...> writes: > >> How can I force the prologue to keep this instruction. It is useless >> only in the case that there is no function call or no alloca. But I >> have a case where there is a function call and it is still removed. > > Make the hard frame pointer register a fixed register, or add it to > EPILOGUE_USES. > > Ian > |
|
|
Re: Preserving the argument spills for GDBDear all,
As I continue to work on this I have found something that is surprising. I wrote this code : int foo (int argc, int argv) { bar (argv, argc); return 0; } On my architecture, this is transformed into the following assembly code: mov r6 = InputReg1 mov InputReg1 = InputReg2 mov InputReg2 = tmp However, I am of course looking at the debug information, and I was surprised to see that : <2><12f>: Abbrev Number: 6 (DW_TAG_formal_parameter) <130> DW_AT_name : argc <135> DW_AT_decl_file : 1 <136> DW_AT_decl_line : 4 <137> DW_AT_type : <af> <13b> DW_AT_location : 0x38 (location list) <2><13f>: Abbrev Number: 6 (DW_TAG_formal_parameter) <140> DW_AT_name : argv <145> DW_AT_decl_file : 1 <146> DW_AT_decl_line : 4 <147> DW_AT_type : <af> <14b> DW_AT_location : 0x6e (location list) This is ok, no problems here. But if I look at the locations given for these variables: 00000038 00000000 0000000c (DW_OP_InputReg1) 00000038 0000000c 0000001c (DW_OP_r6) 00000038 <End of list> 0000006e 00000000 00000010 (DW_OP_InputReg2) 0000006e <End of list> Is there any reason why the compiler does not generate the debug information showing that the InputReg1 is now in InputReg2 and vice-versa? It would seem to me that the debugger would need this information but I may be mistaken. As always, thanks for your input, Jc |
|
|
Re: Preserving the argument spills for GDBOf course:
mov r6 = InputReg1 mov InputReg1 = InputReg2 mov InputReg2 = tmp should read: mov r6 = InputReg1 mov InputReg1 = InputReg2 mov InputReg2 = r6 Sorry about that. Jc On Thu, Nov 12, 2009 at 12:07 PM, Jean Christophe Beyler <jean.christophe.beyler@...> wrote: > Dear all, > > As I continue to work on this I have found something that is surprising. > > I wrote this code : > > int foo (int argc, int argv) > { > bar (argv, argc); > return 0; > } > > On my architecture, this is transformed into the following assembly code: > > mov r6 = InputReg1 > mov InputReg1 = InputReg2 > mov InputReg2 = tmp > > However, I am of course looking at the debug information, and I was > surprised to see that : > > <2><12f>: Abbrev Number: 6 (DW_TAG_formal_parameter) > <130> DW_AT_name : argc > <135> DW_AT_decl_file : 1 > <136> DW_AT_decl_line : 4 > <137> DW_AT_type : <af> > <13b> DW_AT_location : 0x38 (location list) > <2><13f>: Abbrev Number: 6 (DW_TAG_formal_parameter) > <140> DW_AT_name : argv > <145> DW_AT_decl_file : 1 > <146> DW_AT_decl_line : 4 > <147> DW_AT_type : <af> > <14b> DW_AT_location : 0x6e (location list) > > This is ok, no problems here. But if I look at the locations given for > these variables: > 00000038 00000000 0000000c (DW_OP_InputReg1) > 00000038 0000000c 0000001c (DW_OP_r6) > 00000038 <End of list> > 0000006e 00000000 00000010 (DW_OP_InputReg2) > 0000006e <End of list> > > Is there any reason why the compiler does not generate the debug > information showing that the InputReg1 is now in InputReg2 and > vice-versa? It would seem to me that the debugger would need this > information but I may be mistaken. > > As always, thanks for your input, > Jc > |
| Free embeddable forum powered by Nabble | Forum Help |