Have the debugger show an away with a dynamic size?

Hi. I searched and the closest thing I could find was this http://lists.llvm.org/pipermail/llvm-dev/2018-February/121348.html

Currently a known sized array looks and debugs as expected. I use llvm.dbg.declare with DICompositeType tag: DW_TAG_array_type and the size field. In my language arrays are always passed around with a pointer and size pair. I’d like debugging to show up as nicely instead of a pointer addr with no information about the elements. How would I do this? I don’t use the C API, I output llvm-ir directly. I was hoping I can call llvm.dbg.declare/addr/value to specify the pointer, name and size of the variable but I really have no idea how to pass the size to the debugger.``

If you use the Clang options -emit-llvm -S it will produce a .ll file containing the textual IR produced by Clang.

Use this to compile a simple C example using a VLA and it should give you a model of the IR and metadata you would need to produce. I used a source something like this:

int foo(int s) {

int a[s];

int i;

for (i = 0; i < s; ++i)

a[i] = s;

return 0;

}

What I see is a DILocalVariable for “a” that has a type that is a DICompositeType with DW_TAG_array_type, and the elements array of the DICompositeType points to a DISubrange whose count points to a DILocalVariable that is the upper bound.

The resulting DWARF looks okay to me, although I admit I haven’t actually tried running gdb on it to make sure.

I haven’t looked up the DIBuilder APIs, if that’s what you are looking for, but based on what you said, it sounds like you would be able to work that out yourself.

HTH,

–paulr

Take a look at the IR clang produces for C99 variable-length arrays.

– adrian

Thanks for the suggestions but it doesn’t appear to be working correctly for me. I tried building the below after seeing the results with “clang -g -std=c99 test.c” and got the same result

LLDB thinks MyArray is 81 elements long even though 81 and 80 doesn’t show up anywhere in the llvm-ir (I tried again using an llvm ir file made by clang -g -std=c99 test.c -S -emit-llvm and clang -g test.ll)

$ cat test.c
int foo(int s) {
int MyArray[s];
int i;
for (i = 0; i < s; ++i)
MyArray[i] = s;
return 0;
}

int main(){
foo(5);
return 0;
}
$ clang -g test.c
$ lldb ./a.out
(lldb) target create “./a.out”
Current executable set to ‘./a.out’ (x86_64).
(lldb) break set -f test.c -l 6
Breakpoint 1: where = a.out`foo + 101 at test.c:7, address = 0x0000000000400505
(lldb) r
Process 3205 launched: ‘./a.out’ (x86_64)
Process 3205 stopped

  • thread #1, name = ‘a.out’, stop reason = breakpoint 1.1
    frame #0: 0x0000000000400505 a.out`foo(s=5) at test.c:7
    4 for (i = 0; i < s; ++i)
    5 MyArray[i] = s;
    6 return 0;
    → 7 }
    8
    9 int main(){
    10 foo(5);
    (lldb) frame variable
    (int) s = 5
    (unsigned long) __vla_expr0 = 5
    (int) i = 5
    (int [81]) MyArray = {
    [0] = 5
    [1] = 5
    [2] = 5
    [3] = 5
    [4] = 5
    [5] = 0
    [6] = -136481184
    [7] = 32767
    [8] = -8408
    [9] = 32767
    [10] = -8544
    [11] = 32767
    [12] = 1
    [13] = 5
    [14] = 5
    [15] = 0
    [16] = -8512
    [17] = 32767
    [18] = 0
    [19] = 5
    [20] = -8432
    [21] = 32767
    [22] = 4195641
    [23] = 0
    [24] = -8208
    [25] = 32767
    [26] = 0
    [27] = 0
    [28] = 4195664
    [29] = 0
    [30] = -140485737
    [31] = 32767
    [32] = 0
    [33] = 32
    [34] = -8200
    [35] = 32767
    [36] = 0
    [37] = 1
    [38] = 4195616
    [39] = 0
    [40] = 0
    [41] = 0
    [42] = -1953144313
    [43] = 1284291557
    [44] = 4195248
    [45] = 0
    [46] = -8208
    [47] = 32767
    [48] = 0
    [49] = 0
    [50] = 0
    [51] = 0
    [52] = 1064657415
    [53] = -1284291430
    [54] = 933978631
    [55] = -1284287451
    [56] = 0
    [57] = 32767
    [58] = 0
    [59] = 0
    [60] = 0
    [61] = 0
    [62] = -136423629
    [63] = 32767
    [64] = -136530376
    [65] = 32767
    [66] = 386784
    [67] = 0
    [68] = 0
    [69] = 0
    [70] = 0
    [71] = 0
    [72] = 0
    [73] = 0
    [74] = 4195248
    [75] = 0
    [76] = -8208
    [77] = 32767
    [78] = 4195290
    [79] = 0
    [80] = -8216
    }

That is interesting. According to LLDB's test/lang/c/vla/* frame variable for a VLA is supposed to work. Frame variable is also supposed to hide the __vla_expr0 artificial helper variable. Is this an older LLDB from your system or an LLDB you built from source? If yes, would you mind filing a bugreport about this?

thanks,
adrian

It looks like I wasn’t careful and mixed version. I compiled with clang-9 but used lldb-6. Surprisingly this was the only error I notice when mixing these version. I could swear I tried compiling with clang-6. I’d double check but it appears that installing lldb-9 removed lldb(-6) from my system
Thanks for pointing me in the right direction

I added the VLA support to clang and lldb about a year ago, so you’ll need fairly recent version of both for it to work.

– adrian