[Lldb-commits] [lldb] [lldb] Skip local variable declarations at start of Wasm function (PR #190093)
Maarten Steevens via lldb-commits
lldb-commits at lists.llvm.org
Thu Apr 2 01:39:05 PDT 2026
MaartenS11 wrote:
For just disassembly it appears to work (although the addresses are shifted):
```
llvm-project/build/bin/lldb test-dbg.wasm
(lldb) target create "test-dbg.wasm"
Current executable set to '/Users/maarten/Projects/tinygo-warduino-test/tmp/test-dbg.wasm' (wasm32).
(lldb) disassemble -n _main
test-dbg.wasm`_main:
test-dbg.wasm[0x81] <+3>: global.get 0
test-dbg.wasm[0x87] <+9>: i32.const 16
test-dbg.wasm[0x89] <+11>: i32.sub
test-dbg.wasm[0x8a] <+12>: local.set 0
test-dbg.wasm[0x8c] <+14>: local.get 0
test-dbg.wasm[0x8e] <+16>: global.set 0
test-dbg.wasm[0x94] <+22>: local.get 0
test-dbg.wasm[0x96] <+24>: i32.const 0
test-dbg.wasm[0x98] <+26>: i32.store 12
test-dbg.wasm[0x9b] <+29>: block
test-dbg.wasm[0x9d] <+31>: loop ; label2:
test-dbg.wasm[0x9f] <+33>: local.get 0
test-dbg.wasm[0xa1] <+35>: i32.load 12
test-dbg.wasm[0xa4] <+38>: i32.const 50
test-dbg.wasm[0xa6] <+40>: i32.lt_s
test-dbg.wasm[0xa7] <+41>: i32.const 1
test-dbg.wasm[0xa9] <+43>: i32.and
test-dbg.wasm[0xaa] <+44>: i32.eqz
test-dbg.wasm[0xab] <+45>: br_if 1 ; 1: up to label2
test-dbg.wasm[0xad] <+47>: local.get 0
test-dbg.wasm[0xaf] <+49>: i32.load 12
test-dbg.wasm[0xb2] <+52>: call 0
test-dbg.wasm[0xb8] <+58>: local.get 0
test-dbg.wasm[0xba] <+60>: i32.load 12
test-dbg.wasm[0xbd] <+63>: call 1
test-dbg.wasm[0xc3] <+69>: call 0
test-dbg.wasm[0xc9] <+75>: local.get 0
test-dbg.wasm[0xcb] <+77>: local.get 0
test-dbg.wasm[0xcd] <+79>: i32.load 12
test-dbg.wasm[0xd0] <+82>: i32.const 1
test-dbg.wasm[0xd2] <+84>: i32.add
test-dbg.wasm[0xd3] <+85>: i32.store 12
test-dbg.wasm[0xd6] <+88>: br 0 ; 0: up to label3
test-dbg.wasm[0xd8] <+90>: end
test-dbg.wasm[0xd9] <+91>: end
test-dbg.wasm[0xda] <+92>: local.get 0
test-dbg.wasm[0xdc] <+94>: i32.const 16
test-dbg.wasm[0xde] <+96>: i32.add
test-dbg.wasm[0xdf] <+97>: global.set 0
test-dbg.wasm[0xe5] <+103>: return
test-dbg.wasm[0xe6] <+104>: end
(lldb)
```
Which matches with the instructions seen in objdump:
```
0000e3 func[2] <_main>:
0000e4: 01 7f | local[0] type=i32
0000e6: 23 80 80 80 80 00 | global.get 0 <__stack_pointer>
0000ec: 41 10 | i32.const 16
0000ee: 6b | i32.sub
0000ef: 21 00 | local.set 0
0000f1: 20 00 | local.get 0
0000f3: 24 80 80 80 80 00 | global.set 0 <__stack_pointer>
0000f9: 20 00 | local.get 0
0000fb: 41 00 | i32.const 0
0000fd: 36 02 0c | i32.store 2 12
000100: 02 40 | block
000102: 03 40 | loop
000104: 20 00 | local.get 0
000106: 28 02 0c | i32.load 2 12
000109: 41 32 | i32.const 50
00010b: 48 | i32.lt_s
00010c: 41 01 | i32.const 1
00010e: 71 | i32.and
00010f: 45 | i32.eqz
000110: 0d 01 | br_if 1
000112: 20 00 | local.get 0
000114: 28 02 0c | i32.load 2 12
000117: 10 80 80 80 80 00 | call 0 <print_int>
00011d: 20 00 | local.get 0
00011f: 28 02 0c | i32.load 2 12
000122: 10 81 80 80 80 00 | call 1 <fib>
000128: 10 80 80 80 80 00 | call 0 <print_int>
00012e: 20 00 | local.get 0
000130: 20 00 | local.get 0
000132: 28 02 0c | i32.load 2 12
000135: 41 01 | i32.const 1
000137: 6a | i32.add
000138: 36 02 0c | i32.store 2 12
00013b: 0c 00 | br 0
00013d: 0b | end
00013e: 0b | end
00013f: 20 00 | local.get 0
000141: 41 10 | i32.const 16
000143: 6a | i32.add
000144: 24 80 80 80 80 00 | global.set 0 <__stack_pointer>
00014a: 0f | return
00014b: 0b | end
```
On the other hand the moment I start debugging, the instructions suddenly look a bit strange:
```
(lldb) disassemble -n _main
test-dbg.wasm`_main:
-> 0xe6 <+3>: end
0xe7 <+4>: loop unknown_type ; label0:
0xe9 <+6>: return
0xea <+7>: end
```
It seems that the addresses are now shifted regardless of when I'm debugging or not. At `0xe6` there is an `end` according to lldb (see above). But according to objdump it's supposed to be the first instruction of the function `global.get 0`.
Looking at `disassemble -s 0x81 -c 20`, with `0x81` being the address I got from the first disassembly when not debugging I get the expected instructions. So the shift to skip the locals appears to work but the adresses are all shifted by a certain amount.
```
(lldb) disassemble -s 0x81 -c 20
test-dbg.wasm`fib:
0x81 <+26>: global.get 0
0x87 <+32>: i32.const 16
0x89 <+34>: i32.sub
0x8a <+35>: local.set 0
0x8c <+37>: local.get 0
0x8e <+39>: global.set 0
0x94 <+45>: local.get 0
0x96 <+47>: i32.const 0
0x98 <+49>: i32.store 12
0x9b <+52>: block
0x9d <+54>: loop ; label2:
0x9f <+56>: local.get 0
0xa1 <+58>: i32.load 12
0xa4 <+61>: i32.const 50
0xa6 <+63>: i32.lt_s
0xa7 <+64>: i32.const 1
0xa9 <+66>: i32.and
0xaa <+67>: i32.eqz
0xab <+68>: br_if 1 ; 1: up to label2
0xad <+70>: local.get 0
```
https://github.com/llvm/llvm-project/pull/190093
More information about the lldb-commits
mailing list