[LLVMdev] inspecting value of formal parameter in gdb for x86

Seb babslachem at gmail.com
Tue Feb 28 05:34:08 PST 2012


Hi all,

I'm generating code using CLANG + LLVM 2.9 and would like to inspect formal
parameter value for x86 32-bit when -O2 -g is used.
It seems that when code is optimized by the compiler DWARF information
generated doesn't allow to inspect value of parameter.
Trying to inspect parameter value in GDB, parameter is marked as optimized
by the compiler and thus I can't track its value.
A simple example to reproduce the problem is compile following code as
follows:

clang -m32 -O2 -g -c argpass.c

extern void bar(int ) ;
extern void zzz() ;

void foo(int c)
{
    bar(c) ;
    if (c == 0)
        zzz() ;
}


Looking at LLVM code generated, I've got:

; ModuleID = 'argpass.c'
target datalayout =
"e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:32:32-n8:16:32"
target triple = "i386-unknown-linux-gnu"

define void @foo(i32 %c) nounwind {
  tail call void @llvm.dbg.value(metadata !{i32 %c}, i64 0, metadata !5),
!dbg !7
  tail call void @bar(i32 %c) nounwind, !dbg !8
  %1 = icmp eq i32 %c, 0, !dbg !10
  br i1 %1, label %2, label %3, !dbg !10

; <label>:2                                       ; preds = %0
  tail call void (...)* @zzz() nounwind, !dbg !11
  br label %3, !dbg !11

; <label>:3                                       ; preds = %2, %0
  ret void, !dbg !12
}

declare void @bar(i32)

declare void @zzz(...)

declare void @llvm.dbg.value(metadata, i64, metadata) nounwind readnone

!llvm.dbg.sp = !{!0}
!llvm.dbg.lv.foo = !{!5}

!0 = metadata !{i32 589870, i32 0, metadata !1, metadata !"foo", metadata
!"foo", metadata !"", metadata !1, i32 6, metadata !3, i1 false, i1 true,
i32 0, i32 0, i32 0, i32 256, i1 true, void (i32)* @foo} ; [
DW_TAG_subprogram ]
!1 = metadata !{i32 589865, metadata !"argpass.c", metadata
!"/home/deldon/Work/OpenCL/DEBUG", metadata !2} ; [ DW_TAG_file_type ]
!2 = metadata !{i32 589841, i32 0, i32 12, metadata !"argpass.c", metadata
!"/home/deldon/Work/OpenCL/DEBUG", metadata !"clang version 2.9
(tags/RELEASE_29/final)", i1 true, i1 true, metadata !"", i32 0} ; [
DW_TAG_compile_unit ]
!3 = metadata !{i32 589845, metadata !1, metadata !"", metadata !1, i32 0,
i64 0, i64 0, i32 0, i32 0, i32 0, metadata !4, i32 0, i32 0} ; [
DW_TAG_subroutine_type ]
!4 = metadata !{null}
!5 = metadata !{i32 590081, metadata !0, metadata !"c", metadata !1, i32
16777221, metadata !6, i32 0} ; [ DW_TAG_arg_variable ]
!6 = metadata !{i32 589860, metadata !2, metadata !"int", null, i32 0, i64
32, i64 32, i64 0, i32 0, i32 5} ; [ DW_TAG_base_type ]
!7 = metadata !{i32 5, i32 14, metadata !0, null}
!8 = metadata !{i32 7, i32 5, metadata !9, null}
!9 = metadata !{i32 589835, metadata !0, i32 6, i32 1, metadata !1, i32 0}
; [ DW_TAG_lexical_block ]
!10 = metadata !{i32 8, i32 5, metadata !9, null}
!11 = metadata !{i32 9, i32 9, metadata !9, null}
!12 = metadata !{i32 10, i32 1, metadata !9, null}

As we can see 'c' parameter has been optimized and llvm.dbg.value is used
to track its DWARF location.
Now when I look at DWARF informations for object file using readelf
--debug-dump, I've got for 'c' param:

...
<2><81>: Abbrev Number: 3 (DW_TAG_formal_parameter)
    <82>   DW_AT_name        : c
    <84>   DW_AT_decl_file   : 1
    <85>   DW_AT_decl_line   : 5
    <86>   DW_AT_type        : <0x8d>
    <8a>   DW_AT_location    : 1 byte block: 54     (DW_OP_reg4)
...

Looking at assembly code I've got:

...
foo:                                    # @foo
.Lfunc_begin0:
    .loc    1 6 0
.Ltmp3:
# BB#0:
    pushl    %ebp
.Ltmp0:
    movl    %esp, %ebp
.Ltmp1:
    pushl    %esi
    pushl    %eax
.Ltmp2:
    #DEBUG_VALUE: foo:c <- ESP+4294967295 # argpass.c:5:14
    movl    8(%ebp), %esi
    .loc    1 7 5
.Ltmp4:
    movl    %esi, (%esp)            # argpass.c:7:5
    calll    bar                     # argpass.c:7:5
    testl    %esi, %esi
    je    .LBB0_2
# BB#1:
    .loc    1 10 1
.Ltmp5:
    addl    $4, %esp                # argpass.c:10:1
.Ltmp6:
    #DEBUG_VALUE: foo:c <- ESP+4294967295
    popl    %esi                    # argpass.c:10:1
    popl    %ebp                    # argpass.c:10:1
    ret                             # argpass.c:10:1

...

'c' parameter is indeed stored in location 8(%ebp).
If I use a different compiler (PGI C compiler):
pgcc -tp=k8-32 -O2 -g -c argpass.c

I've got following DWARF information for 'c' parameter:

...
 <2><68>: Abbrev Number: 3 (DW_TAG_formal_parameter)
    <69>   DW_AT_name        : c
    <6b>   DW_AT_start_scope : 0x3
    <6f>   DW_AT_type        : <0x77>
    <73>   DW_AT_location    : 2 byte block: 91 8     (DW_OP_fbreg: 8)
...

and value of 'c' can be inspected in GDB. So my questions are:

Is there a way to enforce clang to generate DWARF information similar to
pgcc ?

For the x86 target, a C argument is passed by value on the stack.
In the generated code, we can refer to the stack location of the
argument as created the caller.  Ideally, for the dwarf DIE of the
argument,  we would like see a DWARF location expression for the
argument which represents its location on the (caller's) stack.

Is there a method in the metadata to effect this type of location
expression?
In other words, is there a way in LLVM to write metadata so that DWARF
location would be stack related for x86 ?

Thanks for your answer
Best Regards
Seb
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20120228/d1b7cda8/attachment.html>


More information about the llvm-dev mailing list