DynamoRIO / DynamoRIO/dynamorio
recreate_app_state_from_ilist instrs mismatch with L0_filter_until_instrs
- Dominant language
- C
- Stars
- 3.2k
- Forks
- 629
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 30
Description
If the burst_gencode test is run with -L0_filter_until_instrs X by setting it in the options at https://github.com/DynamoRIO/dynamorio/blob/34fbc25899c45727949332a43050d746aafc83d8/clients/drcachesim/tests/burst_gencode.cpp#L302, it hits the following assert while handling the ud2 (which the test app makes on purpose to test signals in gencode).
```
SYSLOG_ERROR: Application dynamorio/suite/tests/bin/tool.drcacheoff.gencode (1415995). Internal Error: DynamoRIO debug check failure: /usr/local/google/home/sharmaabhinav/dr/src/i6466-3/core/unix/signal.c:3131 false
```
The proximal cause seems to be hitting this case during recreate_app_state_from_ilist: https://github.com/DynamoRIO/dynamorio/blob/34fbc25899c45727949332a43050d746aafc83d8/core/translate.c#L1027
This happens when, while walking the ilist looking for the faulting instr, we overshoot the target_cache pc. I printed out the instr disassembly at each iteration for the ilist instr and the instr at cpc, which should both match. Looks like they start mismatching very early on:
instrs in the given ilist:
```
ilist for recreation:
TAG 0x00007f3128700000
+0 m4 @0x00007f2ee81f4af0 48 a1 48 f4 a5 49 19 mov 0x0000561949a5f448[8byte] -> %rax
56 00 00
+10 m4 @0x00007f2ee81f0a18
+10 m4 @0x00007f2ee81f3ff8 48 3d 03 00 00 00 cmp %rax $0x0000000000000003
+16 m4 @0x00007f2ee81f13c8 0f 85 fa ff ff ff jnz @0x00007f2ee81f3998[8byte]
+22 L3 @0x00007f2ee81f0b28 90 nop
+23 L3 @0x00007f2ee81f4818 b8 42 07 00 00 mov $0x00000742 -> %eax
+28 L3 @0x00007f2ee81f4570 b8 27 04 00 00 mov $0x00000427 -> %eax
...
```
instrs manually disassembled at cpc:
```
cpc 5619093cb73c target_cache 5619093cb869
mov 0x0000561949a5f448[8byte] -> %rax # corresponds to mov 0x0000561949a5f448[8byte] -> %rax in the ilist
bytes: 48 8b 05 05 3d 69 40
cpc 5619093cb746 target_cache 5619093cb869
add %al (%rax)[1byte] -> (%rax)[1byte] # corresponds to cmp %rax $0x0000000000000003 in the ilist
bytes:00 00
cpc 5619093cb74c target_cache 5619093cb869
add %al (%rax)[1byte] -> (%rax)[1byte] # corresponds to jnz @0x00007f2ee81f3998[8byte] in the ilist
bytes:00 00
```
The very first mov instr in the ilist is 10 byte, but when it is disassembled from cpc, it seems to be only 7 bytes. This then mis-aligns all later instrs.
Surprising that DR disassembles both as `mov 0x0000561949a5f448[8byte]`. When I put in those bytes in gdb, it gave me:
```
(gdb) x/10xb a
0x7fffffffd9c1: 0x48 0xa1 0x48 0xf4 0xa5 0x49 0x19 0x56
0x7fffffffd9c9: 0x00 0x00
(gdb) x/10i a
0x7fffffffd9c1: movabs 0x561949a5f448,%rax
0x7fffffffd9cb: add %al,(%rax)
(gdb) x/10xb a
0x7fffffffd9c1: 0x48 0x8b 0x05 0x05 0x3d 0x69 0x40 0x00
0x7fffffffd9c9: 0x00 0x00
(gdb) x/10i a
0x7fffffffd9c1: mov 0x40693d05(%rip),%rax # 0x8000406916cd
0x7fffffffd9c8: add %al,(%rax)
```
I don't know whether this issue is limited to only gencode. I don't see any non-gencode tests that trigger state restore with L0_filter_until_instrs also set.
Contributor guide
Research direction
Start by enabling -L0_filter_until_instrs in clients/drcachesim/tests/burst_gencode.cpp around line 302 and running burst_gencode. Read recreate_app_state_from_ilist in core/translate.c around line 1027 and the assertion in core/unix/signal.c:3131, comparing the ilist and target_cache instruction lengths. Done means the filtered gencode signal case no longer asserts or misaligns instruction recreation.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, cpp
- Domain
- compilers, devtools, testing-qa
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100