Bug 449383 - Exception in vm.c when evaluation Ada expression
Summary: Exception in vm.c when evaluation Ada expression
Status: RESOLVED FIXED
Alias: None
Product: TCF
Classification: Tools
Component: Agent (show other bugs)
Version: unspecified   Edit
Hardware: PC Linux
: P3 critical (vote)
Target Milestone: 1.3   Edit
Assignee: Project Inbox CLA
QA Contact: Eugene Tarassov CLA
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-10-30 13:49 EDT by xavier pouyollon CLA
Modified: 2015-06-16 03:17 EDT (History)
0 users

See Also:


Attachments
Linux executable to reproduce issue. (386.53 KB, application/x-gzip)
2014-10-30 13:49 EDT, xavier pouyollon CLA
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description xavier pouyollon CLA 2014-10-30 13:49:36 EDT
Created attachment 248283 [details]
Linux executable to reproduce issue.

Hi Eugene,

In the attached tarball, linux.ex is the ADA Linux executable.
Put a breakpoint in foo.adb:31
When on line :
   procedure Process (R : Record_Type) is
open expression view and add 'r'

I have the following error: "Invalid address of containing object".
Evaluate_expression fails here:
            if (state->args_cnt == 0) str_exception(ERR_INV_ADDRESS, "Invalid address of containing object");

As far as I understand, we try to analyze die:
 <2><88a>: Abbrev Number: 20 (DW_TAG_structure_type)
    <88b>   DW_AT_name        : (indirect string, offset: 0xa83): foo__record_type
    <88f>   DW_AT_byte_size   : 11 byte block: 97 23 4 6 97 6 99 f8 3 0 0

The 99 is an OP_call4 to <3f8> + <58d>

 <1><975>: Abbrev Number: 27 (DW_TAG_dwarf_procedure)
    <976>   DW_AT_location    : 6 byte block: 15 0 34 1e 16 13  (DW_OP_pick: 0; DW_OP_lit4; DW_OP_mul; DW_OP_swap; DW_OP_drop)
 <1><97d>: Abbrev Number: 27 (DW_TAG_dwarf_procedure)
    <97e>   DW_AT_location    : 6 byte block: 15 0 34 1e 16 13  (DW_OP_pick: 0; DW_OP_lit4; DW_OP_mul; DW_OP_swap; DW_OP_drop)
 <1><985>: Abbrev Number: 27 (DW_TAG_dwarf_procedure)
    <986>   DW_AT_location    : 27 byte block: 15 0 99 e8 3 0 0 15 2 99 f0 3 0 0 22 23 17 c fc ff ff ff 1a 16 13 16 13  (DW_OP_pick: 0; DW_OP_call4: <0x975>; DW_OP_pick: 2; DW_OP_call4: <0x97d>; DW_OP_plus; DW_OP_plus_uconst: 23; DW_OP_const4u: 4294967292; DW_OP_and; DW_OP_swap; DW_OP_drop; DW_OP_swap; DW_OP_drop)

I can't get a clear understanding of what's going on. Any explanation more than welcome !

Best Regards,
Xavier.
Comment 1 xavier pouyollon CLA 2014-10-31 10:42:27 EDT
As far as I understand, the exception 
            if (state->args_cnt == 0) str_exception(ERR_INV_ADDRESS, "Invalid address of containing object");

seems triggered because there is no knowledge of what the currently evaluated object is. (The DW_OP_push_object_address operation pushes the address of the object currently being evaluated as part of evaluation of a user presented expression.)

It is given by:
 <4><877>: Abbrev Number: 9 (DW_TAG_formal_parameter)
    <878>   DW_AT_name        : r
    <87a>   DW_AT_decl_file   : 1
    <87b>   DW_AT_decl_line   : 31
    <87c>   DW_AT_type        : <0x883>
    <880>   DW_AT_location    : 2 byte block: 91 0      (DW_OP_fbreg: 0)

but <880> does not seem to be processed, at least not yet when  <88f>   DW_AT_byte_size  is being evaluated.

Is my understanding correct ?

Best Regards,
Xavier.
Comment 2 Eugene Tarassov CLA 2014-10-31 18:13:56 EDT
(In reply to xavier pouyollon from comment #1)
> As far as I understand, the exception 
>             if (state->args_cnt == 0) str_exception(ERR_INV_ADDRESS,
> "Invalid address of containing object");
> 
> seems triggered because there is no knowledge of what the currently
> evaluated object is. (The DW_OP_push_object_address operation pushes the
> address of the object currently being evaluated as part of evaluation of a
> user presented expression.)
> 
> It is given by:
>  <4><877>: Abbrev Number: 9 (DW_TAG_formal_parameter)
>     <878>   DW_AT_name        : r
>     <87a>   DW_AT_decl_file   : 1
>     <87b>   DW_AT_decl_line   : 31
>     <87c>   DW_AT_type        : <0x883>
>     <880>   DW_AT_location    : 2 byte block: 91 0      (DW_OP_fbreg: 0)
> 
> but <880> does not seem to be processed, at least not yet when  <88f>  
> DW_AT_byte_size  is being evaluated.
> 
> Is my understanding correct ?
> 
> Best Regards,
> Xavier.

Yes, in ADA, an attribute evaluation might need address of the related object. Simple solution is to calculate object address always, but it would slow down symbol resolution for C/C++. I have changed the code to re-evaluate attribute with address if the evaluation has returned "Invalid address of containing object".

Fixed.
Thanks!
Comment 3 xavier pouyollon CLA 2014-11-03 11:43:41 EST
Hi Eugene,

Many thanks for fixing this.

> Simple solution is to calculate object address always, but it would slow down symbol resolution for C/C++.

I've tried to implement that but got lost.

> I have changed the code to re-evaluate attribute with address if the evaluation has returned "Invalid address of containing object".

As far as I understand, you call get_variable_num_prop on the following attributes : AT_byte_size and AT_upper_bound / AT_lower_bound. 

I'm not sure GNAT won't generate Dwarf expression on other tags...

I've tried to debug linux.ex : The behaviour is wrong. When you break at foo.adb:31 and look at the structure, i3 and i2 are wrong. According to the test code, they should be 2 & 3. They have a Dwarf expression for AT_data_member_location, whereas i1 has just DW_AT_data_member_location: 8.
For clarity, I'll make another bugzilla.

Thanks !
Xavier.
Comment 4 xavier pouyollon CLA 2014-11-04 08:37:44 EST
Hi Eugene,

Got this from compiler team:

"GNAT may generate dwarf expressions on a few attributes, but I guess
that you are mostly interested in the possible occurences of
push_object_address here (e.g. constants can contains dwarf
expressions, but they won't contain push_object_address, so I'll
exclude them for the list. Same thing for AT_frame_base, no reason to
have push_object_address there).

So, as of today, here is the list of attributes where you may find
this operation:
* location, data_member_location, data_location;
* bit_size, byte_size, bit_stride, byte_stride;
* upper_bound, lower_bound.

To this list, you may add vtable_elem_location: GCC uses for C++
only for now but may be useful for GNAT in the future, in order to
support tagged records (= Ada "classes").

As I am on it, I'll mention also that gcc generates
push_object_address in AT_string_length, AT_associated and
AT_allocated in the case of Fortran 90, as exemplified by section D.2.1
of the dwarf 4 standard. A priori these would not be needed for Ada
though.

We may realize that we need to add other occurences later on,
staying in the bounds of what the standard allows in section 7;
we would try to keep you informed in that case."

Best Regards,
Xavier.