[llvm-dev] A question to the DWARF experts on symbol indirection

via llvm-dev llvm-dev at lists.llvm.org
Thu Jul 26 11:07:37 PDT 2018


+ Adrian in case he might have insight into the dbg.value question.

> -----Original Message-----
> From: Nat! [mailto:nat at mulle-kybernetik.com]
> Sent: Thursday, July 26, 2018 1:39 PM
> To: Robinson, Paul; t.p.northover at gmail.com
> Cc: llvm-dev at lists.llvm.org
> Subject: Re: [llvm-dev] A question to the DWARF experts on symbol
> indirection
> 
> On 25.07.2018 15:41, paul.robinson at sony.com wrote:Is it possible to emit
> DWARF statements, so that in the debugger the
> >>> parameter _param is hidden and the visibility is a and b, without a
> >> _param-> prefix ?
> >>
> >> It's certainly possible in LLVM IR. @llvm.dbg.declare and so on can
> >> associate arbitrary Values in a function with whatever name you want.
> > DWARF expressions are certainly powerful enough to describe this.
> I am not so sure about this now, after I tried this today and yesterday
> with limited success.
> The main problem I think is, that_param-> points to a location, that
> isn't a fixed offset relative to the stack pointer.
> 
> When I run my IR code through llc, llc was unable to provide a location
> for the debugger. This might be more a limitation of llvm than of DWARF
> though.

I am pretty sure you are pushing the boundaries of what LLVM knows how
to do.  DWARF itself knows how to access a value at (pointer + offset),
even if LLVM doesn't know how to generate such an expression (yet?).

(This is definitely beyond the boundaries of what I personally know how
to get LLVM to do.  However I did pretty much exactly this in a previous
compiler I worked on, so the DWARF part is certainly feasible.)

> 
> Here is part of a DWARF dump with my two fake formal parameters. But as
> you can see the DW_AT_location is missing, which leads to problems in
> gdb and lldb:

Yes, that would be a problem.  :-)

> 
> 
> ```
>   <2><74>: Abbrev Number: 6 (DW_TAG_formal_parameter)
>      <75>   DW_AT_location    : 2 byte block: 91 68 (DW_OP_fbreg: -24)
>      <78>   DW_AT_name        : (indirect string, offset: 0xfd): _param
>      <7c>   DW_AT_type        : <0xf5>
>      <80>   DW_AT_artificial  : 1
>   <2><80>: Abbrev Number: 7 (DW_TAG_formal_parameter)
>      <81>   DW_AT_name        : (indirect string, offset: 0x104): name
>      <85>   DW_AT_decl_file   : 2
>      <86>   DW_AT_decl_line   : 16
>      <87>   DW_AT_type        : <0x11b>
>      <8b>   DW_AT_artificial  : 1
>   <2><8b>: Abbrev Number: 7 (DW_TAG_formal_parameter)
>      <8c>   DW_AT_name        : (indirect string, offset: 0x112): version
>      <90>   DW_AT_decl_file   : 2
>      <91>   DW_AT_decl_line   : 17
>      <92>   DW_AT_type        : <0x130>
>      <96>   DW_AT_artificial  : 1
> ```
> 
> This information relates to this .ll snippet created from my compiler
> (see below for full glory IR):
> 
> ```
>    %_param.addr = alloca %"struct.Hello::p.printName:version:"*, align 8
>    %0 = getelementptr inbounds %"struct.Hello::p.printName:version:",
> %"struct.Hello::p.printName:version:"* %_param,
> i32 0, i32 0
>    call void @llvm.dbg.declare(metadata i8** %0, metadata !32, metadata
> !DIExpression()), !dbg !34
>    %1 = getelementptr inbounds %"struct.Hello::p.printName:version:",
> %"struct.Hello::p.printName:version:"* %_param,
> i32 0, i32 1
>    call void @llvm.dbg.declare(metadata i32* %1, metadata !33, metadata
> !DIExpression()), !dbg !35
> ```
> 
> ```
> !32 = !DILocalVariable(name: "name", arg: 4, scope: !21, file: !3, line:
> 22, type: !29)
> !33 = !DILocalVariable(name: "version", arg: 5, scope: !21, file: !3,
> line: 23, type: !11)
> !34 = !DILocation(line: 22, column: 29, scope: !21)
> !35 = !DILocation(line: 23, column: 35, scope: !21)
> ```
> 
> I am not sure, if I can compute the DW_AT_location for llvm, but I guess
> that's probably what I will try to do next.
> 
> >> But it looks like you're trying to convince Clang itself to do that.
> >> That's likely to be harder since it's not exactly a natural C mapping;
> >> I suspect a lot depends on just where you're doing your ABI lowering.
> > Also depends on whether you want your debugger to be able to call these
> > functions.
> Until recently I believed, that because lldb uses clang JIT to evaluate
> expressions, that when lldb uses my clang to evaluate "a", the code
> would be generated for "_param->a" and that lldb would access the
> correct value. I lost a little confidence in this though.
> 
> >
> > My guess is that you want to describe the formal parameter as
> artificial,
> > using the proper struct description, so that calls work correctly.
> > Then create local variables whose storage locations work indirectly off
> > the (described as artificial) pointer parameter.
> If I create local storage locations, then wouldn't the debugger see
> stale copied information in cases where the function code modifies an
> argument ?

Sorry, I explained that poorly.  I meant create local variables *in DWARF*
(or metadata, in the frontend) whose storage locations work indirectly off 
the pointer.  You seem to have been heading that direction with formal 
parameters instead of variables, which is the same idea; whether it will
confuse the debugger is a different problem, but the concept is right.

I think Tim's point was that, given you have metadata for the individual
entities (params or vars) "a" and "b", you then need to emit an 
llvm.dbg.value intrinsic that can tie the metadata to the indirect location.  
If you do that, then the mechanism to translate that into a DWARF location
expression should kick in and emit DW_AT_location for you.

I honestly don't know whether LLVM can handle a location expression with
this degree of complexity.  However, definitely there is interest in getting 
it to handle that correctly, because handling more complex expressions is 
key to improving the availability of variables in more-optimized code, and
there is a *lot* of interest in improving debugging of optimized code.

HTH,
--paulr



More information about the llvm-dev mailing list