Eliminate -var-create error for optzd ptr to struct

Message ID 1456273154-28629-1-git-send-email-donb@codesourcery.com
State New, archived
Headers

Commit Message

Don Breazeal Feb. 24, 2016, 12:19 a.m. UTC
  Problem:
This patch eliminates an error thrown when accessing the value of a
pointer to a structure where the pointer has been optimized out.
The error shows up as the rather ugly value of the pointer variable
in Eclipse.

With this change such an access will return "<optimized out>" like
other optimized out variables.  We should throw an error when
dereferencing an optimized-out pointer, but not when just looking
at its value.

Cause:
The error only occurs when '-gdb-set print object on' has been set.
This setting requires GDB to "identify the actual (derived) type of
the object rather than the declared type".  Part of this process
is to dereference the pointer in order to get the type of the thing
that is pointed-to.  Since the pointer has been optimized out, this
is impossible, and an error is thrown.

Fix:
The fix is to simply ignore the 'print object on' setting for
pointers or references to structures when they have been optimized
out.  This means we just get the declared type instead of the actual
type, because in this case that's the best that we can do.

Results:
Attempts to dereference the optimized-out pointer using -var-create
or -data-evaluate-expression will throw an error, but a dereference
using -var-evaluate-expression will return an empty value.  To be
consistent, this last case would also throw an error.  I looked into
this some, enough to confirm that there isn't an obvious fix.  Given
that my goal is just to eliminate the unnecessary error, I stopped here.

I'm working on setting things in motion for a patch to Eclipse that
recognizes optimized-out pointer-to-struct in this scenario and
prevents any subsequent attempt to dereference it from that end.

Testing:
I looked at creating a test case for this, but so far haven't been
able to create anything general enough to include in the test suite.

Tested on bare-metal powerpc board with Linux x86_64 host.

OK?

thanks
--Don

gdb/ChangeLog:
2016-02-23  Don Breazeal  <donb@codesourcery.com>

	* gdb/value.c (value_actual_type): Ignore the 'print object
	  on' setting for pointers and references to structures.

---
 gdb/value.c | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)
  

Comments

Luis Machado Feb. 24, 2016, 1:14 a.m. UTC | #1
On 02/23/2016 09:19 PM, Don Breazeal wrote:
> Problem:
> This patch eliminates an error thrown when accessing the value of a
> pointer to a structure where the pointer has been optimized out.
> The error shows up as the rather ugly value of the pointer variable
> in Eclipse.
>
> With this change such an access will return "<optimized out>" like
> other optimized out variables.  We should throw an error when
> dereferencing an optimized-out pointer, but not when just looking
> at its value.
>
> Cause:
> The error only occurs when '-gdb-set print object on' has been set.
> This setting requires GDB to "identify the actual (derived) type of
> the object rather than the declared type".  Part of this process
> is to dereference the pointer in order to get the type of the thing
> that is pointed-to.  Since the pointer has been optimized out, this
> is impossible, and an error is thrown.
>
> Fix:
> The fix is to simply ignore the 'print object on' setting for
> pointers or references to structures when they have been optimized
> out.  This means we just get the declared type instead of the actual
> type, because in this case that's the best that we can do.
>
> Results:
> Attempts to dereference the optimized-out pointer using -var-create
> or -data-evaluate-expression will throw an error, but a dereference
> using -var-evaluate-expression will return an empty value.  To be
> consistent, this last case would also throw an error.  I looked into
> this some, enough to confirm that there isn't an obvious fix.  Given
> that my goal is just to eliminate the unnecessary error, I stopped here.
>
> I'm working on setting things in motion for a patch to Eclipse that
> recognizes optimized-out pointer-to-struct in this scenario and
> prevents any subsequent attempt to dereference it from that end.
>
> Testing:
> I looked at creating a test case for this, but so far haven't been
> able to create anything general enough to include in the test suite.
>
> Tested on bare-metal powerpc board with Linux x86_64 host.
>
> OK?
>
> thanks
> --Don
>
> gdb/ChangeLog:
> 2016-02-23  Don Breazeal  <donb@codesourcery.com>
>
> 	* gdb/value.c (value_actual_type): Ignore the 'print object
> 	  on' setting for pointers and references to structures.
>
> ---
>   gdb/value.c | 5 +++--
>   1 file changed, 3 insertions(+), 2 deletions(-)
>
> diff --git a/gdb/value.c b/gdb/value.c
> index 738b2b2..50e4f8a 100644
> --- a/gdb/value.c
> +++ b/gdb/value.c
> @@ -1203,9 +1203,10 @@ value_actual_type (struct value *value, int resolve_simple_types,
>         /* If result's target type is TYPE_CODE_STRUCT, proceed to
>   	 fetch its rtti type.  */
>         if ((TYPE_CODE (result) == TYPE_CODE_PTR
> -	  || TYPE_CODE (result) == TYPE_CODE_REF)
> +	   || TYPE_CODE (result) == TYPE_CODE_REF)

Is this just a formatting change?

>   	  && TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (result)))
> -	     == TYPE_CODE_STRUCT)
> +	     == TYPE_CODE_STRUCT
> +	  && !value_optimized_out (value))
>           {
>             struct type *real_type;
>

Otherwise looks OK to me.

As for the testcase, how about one that creates a few pointer variables 
(to basic types, structures, arrays and other meaningful ones) and tries 
to print their original values with the "print object" enabled. This 
would be in MI mode, of course.

I'd expect the error to be thrown in an unpatched gdb and a <optimized 
out> string for the patched debugger.
  
Don Breazeal Feb. 24, 2016, 4:31 p.m. UTC | #2
On 2/23/2016 5:14 PM, Gustavo, Luis wrote:
> On 02/23/2016 09:19 PM, Don Breazeal wrote:
>> Problem:
>> This patch eliminates an error thrown when accessing the value of a
>> pointer to a structure where the pointer has been optimized out.
>> The error shows up as the rather ugly value of the pointer variable
>> in Eclipse.
>>
>> With this change such an access will return "<optimized out>" like
>> other optimized out variables.  We should throw an error when
>> dereferencing an optimized-out pointer, but not when just looking
>> at its value.
>>
>> Cause:
>> The error only occurs when '-gdb-set print object on' has been set.
>> This setting requires GDB to "identify the actual (derived) type of
>> the object rather than the declared type".  Part of this process
>> is to dereference the pointer in order to get the type of the thing
>> that is pointed-to.  Since the pointer has been optimized out, this
>> is impossible, and an error is thrown.
>>
>> Fix:
>> The fix is to simply ignore the 'print object on' setting for
>> pointers or references to structures when they have been optimized
>> out.  This means we just get the declared type instead of the actual
>> type, because in this case that's the best that we can do.
>>
>> Results:
>> Attempts to dereference the optimized-out pointer using -var-create
>> or -data-evaluate-expression will throw an error, but a dereference
>> using -var-evaluate-expression will return an empty value.  To be
>> consistent, this last case would also throw an error.  I looked into
>> this some, enough to confirm that there isn't an obvious fix.  Given
>> that my goal is just to eliminate the unnecessary error, I stopped here.
>>
>> I'm working on setting things in motion for a patch to Eclipse that
>> recognizes optimized-out pointer-to-struct in this scenario and
>> prevents any subsequent attempt to dereference it from that end.
>>
>> Testing:
>> I looked at creating a test case for this, but so far haven't been
>> able to create anything general enough to include in the test suite.
>>
>> Tested on bare-metal powerpc board with Linux x86_64 host.
>>
>> OK?
>>
>> thanks
>> --Don
>>
>> gdb/ChangeLog:
>> 2016-02-23  Don Breazeal  <donb@codesourcery.com>
>>
>> 	* gdb/value.c (value_actual_type): Ignore the 'print object
>> 	  on' setting for pointers and references to structures.
>>
>> ---
>>   gdb/value.c | 5 +++--
>>   1 file changed, 3 insertions(+), 2 deletions(-)
>>
>> diff --git a/gdb/value.c b/gdb/value.c
>> index 738b2b2..50e4f8a 100644
>> --- a/gdb/value.c
>> +++ b/gdb/value.c
>> @@ -1203,9 +1203,10 @@ value_actual_type (struct value *value, int resolve_simple_types,
>>         /* If result's target type is TYPE_CODE_STRUCT, proceed to
>>   	 fetch its rtti type.  */
>>         if ((TYPE_CODE (result) == TYPE_CODE_PTR
>> -	  || TYPE_CODE (result) == TYPE_CODE_REF)
>> +	   || TYPE_CODE (result) == TYPE_CODE_REF)
> 
> Is this just a formatting change?

Yes.  I should have documented that in the ChangeLog.

> 
>>   	  && TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (result)))
>> -	     == TYPE_CODE_STRUCT)
>> +	     == TYPE_CODE_STRUCT
>> +	  && !value_optimized_out (value))
>>           {
>>             struct type *real_type;
>>
> 
> Otherwise looks OK to me.

Thanks for the review, Luis.

> 
> As for the testcase, how about one that creates a few pointer variables 
> (to basic types, structures, arrays and other meaningful ones) and tries 
> to print their original values with the "print object" enabled. This 
> would be in MI mode, of course.
> 
> I'd expect the error to be thrown in an unpatched gdb and a <optimized 
> out> string for the patched debugger.
> 
The main problem so far has been to get the compiler to optimize out the
variables that I want it to optimize out, with a target that is generic
enough that I can generate some assembly code that will run on something
other than a specific version of a CPU.  Trial and error.
  
Pedro Alves Feb. 25, 2016, 12:22 p.m. UTC | #3
On 02/24/2016 04:31 PM, Don Breazeal wrote:
> The main problem so far has been to get the compiler to optimize out the
> variables that I want it to optimize out, with a target that is generic
> enough that I can generate some assembly code that will run on something
> other than a specific version of a CPU.  Trial and error.

Sounds like a job for the testsuite's dwarf assembler?

Thanks,
Pedro Alves
  
Don Breazeal March 28, 2016, 9:33 p.m. UTC | #4
This patchset is follows up on a patch submitted about a month ago,
which eliminated an error caused by an MI -var-create request for
an optimized-out pointer-to-struct.  When 'set print object' is 'on',
GDB tries to obtain the actual type rather than the declared type,
and to do so must dereference the pointer, which is impossible because
it has been optimized out.

The original patch did not include a test; that has now been added.

Patch 1/1: New test for accessing optimized-out pointer-to-struct.

Patch 2/2: The original patch, which eliminates the error when
           accessing an optimized-out-pointer.

The fix was regression tested on a PowerPC board with a Linux x86 host,
and the test was tested on native Linux x86_64.

Thanks,
--Don
  
Yao Qi March 29, 2016, 12:01 p.m. UTC | #5
Don Breazeal <donb@codesourcery.com> writes:

>>> @@ -1203,9 +1203,10 @@ value_actual_type (struct value *value, int resolve_simple_types,
>>>         /* If result's target type is TYPE_CODE_STRUCT, proceed to
>>>   	 fetch its rtti type.  */
>>>         if ((TYPE_CODE (result) == TYPE_CODE_PTR
>>> -	  || TYPE_CODE (result) == TYPE_CODE_REF)
>>> +	   || TYPE_CODE (result) == TYPE_CODE_REF)
>> 
>> Is this just a formatting change?
>
> Yes.  I should have documented that in the ChangeLog.

If it is just a format change, you can move it to a separate patch, and
commit it as obvious.  Don't mix format change with your bug fix patch.
  

Patch

diff --git a/gdb/value.c b/gdb/value.c
index 738b2b2..50e4f8a 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -1203,9 +1203,10 @@  value_actual_type (struct value *value, int resolve_simple_types,
       /* If result's target type is TYPE_CODE_STRUCT, proceed to
 	 fetch its rtti type.  */
       if ((TYPE_CODE (result) == TYPE_CODE_PTR
-	  || TYPE_CODE (result) == TYPE_CODE_REF)
+	   || TYPE_CODE (result) == TYPE_CODE_REF)
 	  && TYPE_CODE (check_typedef (TYPE_TARGET_TYPE (result)))
-	     == TYPE_CODE_STRUCT)
+	     == TYPE_CODE_STRUCT
+	  && !value_optimized_out (value))
         {
           struct type *real_type;