DynamoRIO / DynamoRIO/dynamorio

recreate_app_state_from_ilist instrs mismatch with L0_filter_until_instrs

Open
#6,474 3 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.