Value of structure passed byval to a recurse function not initialized when accessed through GDB

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Value of structure passed byval to a recurse function not initialized when accessed through GDB

Karthik Bhat
Hi All,

I was debugging a clang binary when i found this problem. The
following code is complied with clang.

typedef struct s
{
  short s;
} SVAL;


void recurse (SVAL a, int depth)
{
  a.s = --depth;
  if (depth == 0)
    return;
  else
   recurse(a,depth);
}

int main ()
{
  SVAL s; s.s = 5;
  recurse (s, 5);
  return 0;
}

When i try to access value of a.s in function recurse through gdb(i.e
gdb > p a.s) it gives me an uninitialized value.
The problem occurs only when we have a function call within function
to which we have passed a structure.

Could someone guide me were can i look to fix this issue.

I have started with LowerFormalArguments in X86ISelLowering.cpp file.

Thanks
Karthik
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Value of structure passed byval to a recurse function not initialized when accessed through GDB

Relph, Richard
Karthik,
    At what point within recurse() are you asking gdb to display the value of argument a?
    What I'm wondering about is if the debug information gdb is using to get at a might not be correct at the particular point you are checking a, particularly if that is before the prolog has completed execution.
    The way debug information for arguments pushed on the stack is represented in DWARF requires some effort to get right at every instruction boundary, and the fact that what's being passed is a structure, but one that is less than an integer in size, may be exposing a bug in DWARF generation, not code generation.
    Just a thought.
Richard

On Dec 4, 2012, at 5:34 AM, Karthik Bhat <[hidden email]> wrote:

> Hi All,
>
> I was debugging a clang binary when i found this problem. The
> following code is complied with clang.
>
> typedef struct s
> {
>  short s;
> } SVAL;
>
>
> void recurse (SVAL a, int depth)
> {
>  a.s = --depth;
>  if (depth == 0)
>    return;
>  else
>   recurse(a,depth);
> }
>
> int main ()
> {
>  SVAL s; s.s = 5;
>  recurse (s, 5);
>  return 0;
> }
>
> When i try to access value of a.s in function recurse through gdb(i.e
> gdb > p a.s) it gives me an uninitialized value.
> The problem occurs only when we have a function call within function
> to which we have passed a structure.
>
> Could someone guide me were can i look to fix this issue.
>
> I have started with LowerFormalArguments in X86ISelLowering.cpp file.
>
> Thanks
> Karthik
> _______________________________________________
> LLVM Developers mailing list
> [hidden email]         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>



_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Value of structure passed byval to a recurse function not initialized when accessed through GDB

David Blaikie
In reply to this post by Karthik Bhat
This seems to be another case of PR13303 - since GDB can't figure out
where to break for this function based on the debug info (you'll
notice when you "break recurse" that it's not breaking on a line or
source file, just an address) it's breaking at the very start, before
the prologue

I'm about to commit a fix to this.

On Tue, Dec 4, 2012 at 5:34 AM, Karthik Bhat <[hidden email]> wrote:

> Hi All,
>
> I was debugging a clang binary when i found this problem. The
> following code is complied with clang.
>
> typedef struct s
> {
>   short s;
> } SVAL;
>
>
> void recurse (SVAL a, int depth)
> {
>   a.s = --depth;
>   if (depth == 0)
>     return;
>   else
>    recurse(a,depth);
> }
>
> int main ()
> {
>   SVAL s; s.s = 5;
>   recurse (s, 5);
>   return 0;
> }
>
> When i try to access value of a.s in function recurse through gdb(i.e
> gdb > p a.s) it gives me an uninitialized value.
> The problem occurs only when we have a function call within function
> to which we have passed a structure.
>
> Could someone guide me were can i look to fix this issue.
>
> I have started with LowerFormalArguments in X86ISelLowering.cpp file.
>
> Thanks
> Karthik
> _______________________________________________
> LLVM Developers mailing list
> [hidden email]         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Value of structure passed byval to a recurse function not initialized when accessed through GDB

Karthik Bhat
In reply to this post by Relph, Richard
Hi Relph,
I'm trying to print the value of 'a' while executing  a.s = --depth; I
have used break line number instead of break function so that the
initial prologue part gets executed.
The problem seems to be happening when parameters are pushed into
stack and we call a function recursively.

For example in the code when we have a int s; inside the struct
instead of short s; gdb is able to print the structure value properly.
The difference is when we have a short inside struct we are treating
it as byval parameter object inside
X86TargetLowering::LowerMemArgument were as when we have an "int" it
doesn't treat it as byval.

Thanks



On Tue, Dec 4, 2012 at 9:26 PM, Relph, Richard <[hidden email]> wrote:

> Karthik,
>     At what point within recurse() are you asking gdb to display the value of argument a?
>     What I'm wondering about is if the debug information gdb is using to get at a might not be correct at the particular point you are checking a, particularly if that is before the prolog has completed execution.
>     The way debug information for arguments pushed on the stack is represented in DWARF requires some effort to get right at every instruction boundary, and the fact that what's being passed is a structure, but one that is less than an integer in size, may be exposing a bug in DWARF generation, not code generation.
>     Just a thought.
> Richard
>
> On Dec 4, 2012, at 5:34 AM, Karthik Bhat <[hidden email]> wrote:
>
>> Hi All,
>>
>> I was debugging a clang binary when i found this problem. The
>> following code is complied with clang.
>>
>> typedef struct s
>> {
>>  short s;
>> } SVAL;
>>
>>
>> void recurse (SVAL a, int depth)
>> {
>>  a.s = --depth;
>>  if (depth == 0)
>>    return;
>>  else
>>   recurse(a,depth);
>> }
>>
>> int main ()
>> {
>>  SVAL s; s.s = 5;
>>  recurse (s, 5);
>>  return 0;
>> }
>>
>> When i try to access value of a.s in function recurse through gdb(i.e
>> gdb > p a.s) it gives me an uninitialized value.
>> The problem occurs only when we have a function call within function
>> to which we have passed a structure.
>>
>> Could someone guide me were can i look to fix this issue.
>>
>> I have started with LowerFormalArguments in X86ISelLowering.cpp file.
>>
>> Thanks
>> Karthik
>> _______________________________________________
>> LLVM Developers mailing list
>> [hidden email]         http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>
>
>

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Value of structure passed byval to a recurse function not initialized when accessed through GDB

Karthik Bhat
Hi,
The problem seems to be that in case we have a structure as argument
we pass the value indirectly via a hidden pointer.

Since we are passing value via a pointer we need to do a load in
X86TargetLowering::LowerFormalArguments i.e.

    // If value is passed via pointer - do a load.
    if (VA.getLocInfo() == CCValAssign::Indirect)
      ArgValue = DAG.getLoad(VA.getValVT(), dl, Chain, ArgValue,
                             MachinePointerInfo(), false, false, false, 0);

this part of code should have been executed.
But currently we are getting VA.getLocInfo() as CCValAssign::Full as a
result a load does not happen even though we have passed the value via
a hidden pointer.

Currently this seems to be the problem but i'm not sure as i'm a bit
new to the code. Would like to get input from community if the
analysis is correct and how to go ahead to fix this issue.

Thanks
Karthik






On Wed, Dec 5, 2012 at 10:49 AM, Karthik Bhat <[hidden email]> wrote:

> Hi Relph,
> I'm trying to print the value of 'a' while executing  a.s = --depth; I
> have used break line number instead of break function so that the
> initial prologue part gets executed.
> The problem seems to be happening when parameters are pushed into
> stack and we call a function recursively.
>
> For example in the code when we have a int s; inside the struct
> instead of short s; gdb is able to print the structure value properly.
> The difference is when we have a short inside struct we are treating
> it as byval parameter object inside
> X86TargetLowering::LowerMemArgument were as when we have an "int" it
> doesn't treat it as byval.
>
> Thanks
>
>
>
> On Tue, Dec 4, 2012 at 9:26 PM, Relph, Richard <[hidden email]> wrote:
>> Karthik,
>>     At what point within recurse() are you asking gdb to display the value of argument a?
>>     What I'm wondering about is if the debug information gdb is using to get at a might not be correct at the particular point you are checking a, particularly if that is before the prolog has completed execution.
>>     The way debug information for arguments pushed on the stack is represented in DWARF requires some effort to get right at every instruction boundary, and the fact that what's being passed is a structure, but one that is less than an integer in size, may be exposing a bug in DWARF generation, not code generation.
>>     Just a thought.
>> Richard
>>
>> On Dec 4, 2012, at 5:34 AM, Karthik Bhat <[hidden email]> wrote:
>>
>>> Hi All,
>>>
>>> I was debugging a clang binary when i found this problem. The
>>> following code is complied with clang.
>>>
>>> typedef struct s
>>> {
>>>  short s;
>>> } SVAL;
>>>
>>>
>>> void recurse (SVAL a, int depth)
>>> {
>>>  a.s = --depth;
>>>  if (depth == 0)
>>>    return;
>>>  else
>>>   recurse(a,depth);
>>> }
>>>
>>> int main ()
>>> {
>>>  SVAL s; s.s = 5;
>>>  recurse (s, 5);
>>>  return 0;
>>> }
>>>
>>> When i try to access value of a.s in function recurse through gdb(i.e
>>> gdb > p a.s) it gives me an uninitialized value.
>>> The problem occurs only when we have a function call within function
>>> to which we have passed a structure.
>>>
>>> Could someone guide me were can i look to fix this issue.
>>>
>>> I have started with LowerFormalArguments in X86ISelLowering.cpp file.
>>>
>>> Thanks
>>> Karthik
>>> _______________________________________________
>>> LLVM Developers mailing list
>>> [hidden email]         http://llvm.cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>>
>>
>>

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Value of structure passed byval to a recurse function not initialized when accessed through GDB

Karthik Bhat
In reply to this post by David Blaikie
Hi David,

I think it might not be exactly PR13303 which might be causing the
corruption of struct when accessed through GDB.
This seems to be an ABI problem in clang.
The problem seems to be that when we have pass by value of struct
(having indirect arguments) stack is not aligned properly.

I tried realigning the stack for indirect arguments in(TargetInfo.cpp) -

ABIArgInfo X86_32ABIInfo::getIndirectResult(QualType Ty, bool ByVal)

.....
 if (StackAlign == 0)
        return ABIArgInfo::getIndirect(4, /*ByVal=*/true,
                                   /*Realign=*/true);      // Do a
realign of stack.

...


This seems to have fixed the issue. Also in case we have a large
structure - e.g. -

typedef struct s
{
  long s;
  long i;
  long l;
  long s1;
  long i1;
  long l1;
} SVAL;

in the above mentioned code the same issue(corruption of member
variables when accessed through GDB) was observed which has got fixed
after this change.

Need input if this change is correct.

Thanks

On Wed, Dec 5, 2012 at 1:45 AM, David Blaikie <[hidden email]> wrote:

> This seems to be another case of PR13303 - since GDB can't figure out
> where to break for this function based on the debug info (you'll
> notice when you "break recurse" that it's not breaking on a line or
> source file, just an address) it's breaking at the very start, before
> the prologue
>
> I'm about to commit a fix to this.
>
> On Tue, Dec 4, 2012 at 5:34 AM, Karthik Bhat <[hidden email]> wrote:
>> Hi All,
>>
>> I was debugging a clang binary when i found this problem. The
>> following code is complied with clang.
>>
>> typedef struct s
>> {
>>   short s;
>> } SVAL;
>>
>>
>> void recurse (SVAL a, int depth)
>> {
>>   a.s = --depth;
>>   if (depth == 0)
>>     return;
>>   else
>>    recurse(a,depth);
>> }
>>
>> int main ()
>> {
>>   SVAL s; s.s = 5;
>>   recurse (s, 5);
>>   return 0;
>> }
>>
>> When i try to access value of a.s in function recurse through gdb(i.e
>> gdb > p a.s) it gives me an uninitialized value.
>> The problem occurs only when we have a function call within function
>> to which we have passed a structure.
>>
>> Could someone guide me were can i look to fix this issue.
>>
>> I have started with LowerFormalArguments in X86ISelLowering.cpp file.
>>
>> Thanks
>> Karthik
>> _______________________________________________
>> LLVM Developers mailing list
>> [hidden email]         http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Value of structure passed byval to a recurse function not initialized when accessed through GDB

David Blaikie
On Thu, Dec 6, 2012 at 12:33 AM, Karthik Bhat <[hidden email]> wrote:

> Hi David,
>
> I think it might not be exactly PR13303 which might be causing the
> corruption of struct when accessed through GDB.
> This seems to be an ABI problem in clang.
> The problem seems to be that when we have pass by value of struct
> (having indirect arguments) stack is not aligned properly.
>
> I tried realigning the stack for indirect arguments in(TargetInfo.cpp) -
>
> ABIArgInfo X86_32ABIInfo::getIndirectResult(QualType Ty, bool ByVal)
>
> .....
>  if (StackAlign == 0)
>         return ABIArgInfo::getIndirect(4, /*ByVal=*/true,
>                                    /*Realign=*/true);      // Do a
> realign of stack.
>
> ...
>
>
> This seems to have fixed the issue. Also in case we have a large
> structure - e.g. -
>
> typedef struct s
> {
>   long s;
>   long i;
>   long l;
>   long s1;
>   long i1;
>   long l1;
> } SVAL;
>
> in the above mentioned code the same issue(corruption of member
> variables when accessed through GDB) was observed which has got fixed
> after this change.
>
> Need input if this change is correct.

I haven't looked at this carefully yet (& I'm not the authority on ABI
issues - not sure who pays most attention to this in the backend, John
McCall deals with it mostly in Clang proper but I've CC'd him here in
case things rings any bells for him) but a simple way you could
provide strong motivation for this change is if you can demonstrate
that this is also a correctness issue: If clang/llvm are really
incorrectly implementing the ABI this should cause interoperability
issues if clang is used to compile a caller and gcc a callee to the
same function (or the other way around).

If you can come up with a simple example that demonstrates that it
should be a fairly unquestionable change. (test cases along with the
change all in a patch file help too)

Thanks,
- David

>
> Thanks
>
> On Wed, Dec 5, 2012 at 1:45 AM, David Blaikie <[hidden email]> wrote:
>> This seems to be another case of PR13303 - since GDB can't figure out
>> where to break for this function based on the debug info (you'll
>> notice when you "break recurse" that it's not breaking on a line or
>> source file, just an address) it's breaking at the very start, before
>> the prologue
>>
>> I'm about to commit a fix to this.
>>
>> On Tue, Dec 4, 2012 at 5:34 AM, Karthik Bhat <[hidden email]> wrote:
>>> Hi All,
>>>
>>> I was debugging a clang binary when i found this problem. The
>>> following code is complied with clang.
>>>
>>> typedef struct s
>>> {
>>>   short s;
>>> } SVAL;
>>>
>>>
>>> void recurse (SVAL a, int depth)
>>> {
>>>   a.s = --depth;
>>>   if (depth == 0)
>>>     return;
>>>   else
>>>    recurse(a,depth);
>>> }
>>>
>>> int main ()
>>> {
>>>   SVAL s; s.s = 5;
>>>   recurse (s, 5);
>>>   return 0;
>>> }
>>>
>>> When i try to access value of a.s in function recurse through gdb(i.e
>>> gdb > p a.s) it gives me an uninitialized value.
>>> The problem occurs only when we have a function call within function
>>> to which we have passed a structure.
>>>
>>> Could someone guide me were can i look to fix this issue.
>>>
>>> I have started with LowerFormalArguments in X86ISelLowering.cpp file.
>>>
>>> Thanks
>>> Karthik
>>> _______________________________________________
>>> LLVM Developers mailing list
>>> [hidden email]         http://llvm.cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: Value of structure passed byval to a recurse function not initialized when accessed through GDB

Karthik Bhat
Hi,
There are few clang test cases which address this issue but are not
fixed. E.g. clang/test/CodeGen/x86_32-arguments-linux.c ,
tools/clang/test/CodeGen/x86_32-arguments-darwin.c etc have mentioned
them with a FIXME: note.

Will see if i can come up with some other examples and data.

Thanks

On Thu, Dec 6, 2012 at 10:55 PM, David Blaikie <[hidden email]> wrote:

> On Thu, Dec 6, 2012 at 12:33 AM, Karthik Bhat <[hidden email]> wrote:
>> Hi David,
>>
>> I think it might not be exactly PR13303 which might be causing the
>> corruption of struct when accessed through GDB.
>> This seems to be an ABI problem in clang.
>> The problem seems to be that when we have pass by value of struct
>> (having indirect arguments) stack is not aligned properly.
>>
>> I tried realigning the stack for indirect arguments in(TargetInfo.cpp) -
>>
>> ABIArgInfo X86_32ABIInfo::getIndirectResult(QualType Ty, bool ByVal)
>>
>> .....
>>  if (StackAlign == 0)
>>         return ABIArgInfo::getIndirect(4, /*ByVal=*/true,
>>                                    /*Realign=*/true);      // Do a
>> realign of stack.
>>
>> ...
>>
>>
>> This seems to have fixed the issue. Also in case we have a large
>> structure - e.g. -
>>
>> typedef struct s
>> {
>>   long s;
>>   long i;
>>   long l;
>>   long s1;
>>   long i1;
>>   long l1;
>> } SVAL;
>>
>> in the above mentioned code the same issue(corruption of member
>> variables when accessed through GDB) was observed which has got fixed
>> after this change.
>>
>> Need input if this change is correct.
>
> I haven't looked at this carefully yet (& I'm not the authority on ABI
> issues - not sure who pays most attention to this in the backend, John
> McCall deals with it mostly in Clang proper but I've CC'd him here in
> case things rings any bells for him) but a simple way you could
> provide strong motivation for this change is if you can demonstrate
> that this is also a correctness issue: If clang/llvm are really
> incorrectly implementing the ABI this should cause interoperability
> issues if clang is used to compile a caller and gcc a callee to the
> same function (or the other way around).
>
> If you can come up with a simple example that demonstrates that it
> should be a fairly unquestionable change. (test cases along with the
> change all in a patch file help too)
>
> Thanks,
> - David
>
>>
>> Thanks
>>
>> On Wed, Dec 5, 2012 at 1:45 AM, David Blaikie <[hidden email]> wrote:
>>> This seems to be another case of PR13303 - since GDB can't figure out
>>> where to break for this function based on the debug info (you'll
>>> notice when you "break recurse" that it's not breaking on a line or
>>> source file, just an address) it's breaking at the very start, before
>>> the prologue
>>>
>>> I'm about to commit a fix to this.
>>>
>>> On Tue, Dec 4, 2012 at 5:34 AM, Karthik Bhat <[hidden email]> wrote:
>>>> Hi All,
>>>>
>>>> I was debugging a clang binary when i found this problem. The
>>>> following code is complied with clang.
>>>>
>>>> typedef struct s
>>>> {
>>>>   short s;
>>>> } SVAL;
>>>>
>>>>
>>>> void recurse (SVAL a, int depth)
>>>> {
>>>>   a.s = --depth;
>>>>   if (depth == 0)
>>>>     return;
>>>>   else
>>>>    recurse(a,depth);
>>>> }
>>>>
>>>> int main ()
>>>> {
>>>>   SVAL s; s.s = 5;
>>>>   recurse (s, 5);
>>>>   return 0;
>>>> }
>>>>
>>>> When i try to access value of a.s in function recurse through gdb(i.e
>>>> gdb > p a.s) it gives me an uninitialized value.
>>>> The problem occurs only when we have a function call within function
>>>> to which we have passed a structure.
>>>>
>>>> Could someone guide me were can i look to fix this issue.
>>>>
>>>> I have started with LowerFormalArguments in X86ISelLowering.cpp file.
>>>>
>>>> Thanks
>>>> Karthik
>>>> _______________________________________________
>>>> LLVM Developers mailing list
>>>> [hidden email]         http://llvm.cs.uiuc.edu
>>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev