<table border="1" cellspacing="0" cellpadding="8">
<tr>
<th>Issue</th>
<td>
<a href=https://github.com/llvm/llvm-project/issues/96401>96401</a>
</td>
</tr>
<tr>
<th>Summary</th>
<td>
[lldb] `finish` doesn't work well with sanitizer coverage and if-else-chains.
</td>
</tr>
<tr>
<th>Labels</th>
<td>
new issue
</td>
</tr>
<tr>
<th>Assignees</th>
<td>
</td>
</tr>
<tr>
<th>Reporter</th>
<td>
mvanotti
</td>
</tr>
</table>
<pre>
I'm trying to run the debugger on a program that was compiled with `-fsanitize-coverage=bb,no-prune,trace-pc-guard`, and I want to step-out of all the calls to `__sanitizer_cov_trace_pc_guard`.
I've found that when I attempt to do a `finish` in the `else` case of an `if` with an `else if` clause, lldb gets confused.
See the following example:
```c++
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/random.h>
[[clang::noinline]] void foo(void) {
uint64_t random_num = 0;
ssize_t res = getrandom(&random_num, sizeof(random_num), 0);
assert(res != -1);
assert(static_cast<size_t>(res) == sizeof(random_num));
if (random_num == UINT64_MAX) {
__asm__ volatile("nop");
} else if (random_num == 0) {
__asm__ volatile("nop");
} else if (random_num == 1) {
__asm__ volatile("nop");
} else {
__asm__ volatile("pause");
}
}
int main(void) {
foo();
fprintf(stderr,
"If we are single-stepping, we should have a stop here on main.\n");
return 0;
}
extern "C" [[clang::noinline]] void __sanitizer_cov_trace_pc_guard(uint32_t *) {
// Do (almost) nothing!
__asm__ volatile("pause");
}
extern "C" void __sanitizer_cov_trace_pc_guard_init(uint32_t *, uint32_t *) {}
```
Compiled with:
```
$ clang++ -Wall -Wextra -pedantic -std=c++17 -gdwarf-5 -O0 -fsanitize-coverage=bb,no-prune,trace-pc-guard program.cc -o program
```
Running it under lldb, single stepping, and calling `finish` each time we are in `__sanitizer_cov_trace_pc_guard`:
```
(lldb) target create "./program"
Current executable set to '/home/user/lldb-test/program' (x86_64).
(lldb) breakpoint set --file program.cc --line 21
Breakpoint 1: where = program`foo() + 369 at program.cc:21:5, address = 0x000000000002e631
(lldb) run
Process 3612485 launched: '/home/user/lldb-test/program' (x86_64)
Process 3612485 stopped
* thread #1, name = 'program', stop reason = breakpoint 1.1
frame #0: 0x0000555555582631 program`foo() at program.cc:21:5
18 } else if (random_num == 1) {
19 __asm__ volatile("nop");
20 } else {
-> 21 __asm__ volatile("pause");
22 }
23 }
24
(lldb) s
Process 3612485 stopped
* thread #1, name = 'program', stop reason = step in
frame #0: 0x00005555555824a8 program`__sanitizer_cov_trace_pc_guard((null)=0x0000555555599b50) at program.cc:33:3
30 }
31
32 extern "C" [[clang::noinline]] void __sanitizer_cov_trace_pc_guard(uint32_t *) {
-> 33 // Do (almost) nothing!
34 __asm__ volatile("pause");
35 }
36
(lldb) finish
Process 3612485 stopped
* thread #1, name = 'program', stop reason = step out
frame #0: 0x0000555555582641 program`foo() at program.cc:21:5
18 } else if (random_num == 1) {
19 __asm__ volatile("nop");
20 } else {
-> 21 __asm__ volatile("pause");
22 }
23 }
24
(lldb) s
Process 3612485 stopped
* thread #1, name = 'program', stop reason = step in
frame #0: 0x00005555555824a8 program`__sanitizer_cov_trace_pc_guard((null)=0x0000555555599b54) at program.cc:33:3
30 }
31
32 extern "C" [[clang::noinline]] void __sanitizer_cov_trace_pc_guard(uint32_t *) {
-> 33 // Do (almost) nothing!
34 __asm__ volatile("pause");
35 }
36
(lldb) finish
If we are single-stepping, we should have a stop here on main.
Process 3612485 exited with status = 0 (0x00000000)
(lldb)
```
The outcome is less than ideal: instead of executing until the end of `__sanitizer_cov_trace_pc_guard`, the program executes until the end of the program.
Here is a python script that replicates this behavior (this is how I initially observed the issue):
```python
#!/usr/bin/python3
import lldb
import os
def main():
debugger = lldb.SBDebugger.Create()
debugger.SetAsync(False)
target_prog = './program'
argv = []
envp = []
target = debugger.CreateTargetWithFileAndArch(
target_prog, lldb.LLDB_ARCH_DEFAULT_64BIT
)
assert target.IsValid()
bp = target.BreakpointCreateByName('main')
error = lldb.SBError()
process = target.Launch(
debugger.GetListener(),
argv,
envp,
None,
None,
None,
os.getcwd(),
0, # launch_flags
False, # stop_at_entry
error,
)
assert error.Success(), error
traced_functions = set(['main', 'foo()'])
while process.GetState() == lldb.eStateStopped:
assert len(process.threads) == 1
thread = process.threads[0]
assert thread.IsValid()
frames = thread.get_thread_frames()
assert frames
frame = frames[0]
assert frame.IsValid()
func_name = frame.function.name
if func_name not in traced_functions:
print(f'Stepping out of function {func_name}')
thread.StepOutOfFrame(frame)
continue
print(f'Func {func_name:>10} | Location {os.path.basename(str(frame.line_entry.file)):>10}:{frame.line_entry.line:>3} | pc @ {hex(frame.pc)}')
thread.StepInto()
if __name__ == '__main__':
main()
```
Output:
```
Func main | Location program.cc: 25 | pc @ 0x555555582688
Stepping out of function ::__sanitizer_cov_trace_pc_guard(uint32_t *)
Func main | Location program.cc: 25 | pc @ 0x555555582694
Func main | Location program.cc: 26 | pc @ 0x55555558269b
Func foo() | Location program.cc: 8 | pc @ 0x5555555824c8
Stepping out of function ::__sanitizer_cov_trace_pc_guard(uint32_t *)
Func foo() | Location program.cc: 9 | pc @ 0x5555555824d4
Func foo() | Location program.cc: 10 | pc @ 0x5555555824dc
Stepping out of function __GI___getrandom
Func foo() | Location program.cc: 10 | pc @ 0x5555555824ec
Func foo() | Location program.cc: 11 | pc @ 0x5555555824f0
Stepping out of function ::__sanitizer_cov_trace_pc_guard(uint32_t *)
Func foo() | Location program.cc: 11 | pc @ 0x55555558250b
Func foo() | Location program.cc: 12 | pc @ 0x55555558253f
Stepping out of function ::__sanitizer_cov_trace_pc_guard(uint32_t *)
Func foo() | Location program.cc: 12 | pc @ 0x55555558254f
Stepping out of function ::__sanitizer_cov_trace_pc_guard(uint32_t *)
Func foo() | Location program.cc: 12 | pc @ 0x55555558256a
Func foo() | Location program.cc: 14 | pc @ 0x55555558259e
Stepping out of function ::__sanitizer_cov_trace_pc_guard(uint32_t *)
Func foo() | Location program.cc: 14 | pc @ 0x5555555825ae
Func foo() | Location program.cc: 16 | pc @ 0x5555555825cf
Stepping out of function ::__sanitizer_cov_trace_pc_guard(uint32_t *)
Func foo() | Location program.cc: 16 | pc @ 0x5555555825df
Func foo() | Location program.cc: 18 | pc @ 0x555555582600
Stepping out of function ::__sanitizer_cov_trace_pc_guard(uint32_t *)
Func foo() | Location program.cc: 18 | pc @ 0x555555582610
Func foo() | Location program.cc: 21 | pc @ 0x555555582631
Stepping out of function ::__sanitizer_cov_trace_pc_guard(uint32_t *)
Func foo() | Location program.cc: 21 | pc @ 0x555555582641
Stepping out of function ::__sanitizer_cov_trace_pc_guard(uint32_t *)
```
I haven't tried this with the `lldb` version at trunk yet, will report back once I do.
</pre>
<img width="1px" height="1px" alt="" src="http://email.email.llvm.org/o/eJzsWl9z4jgS_zTKSxeULYOBhzwQGHZTNbdztZm9vTeXsNtYN0ZySTIk--mvWraxSSCTyc1uzVUtlSIgtX7qf-putRHWyp1CvGXTOzZd34jaFdrc7g9CaefkzVZnT7f3jM_24MyTVDtwGkytwBUIGW7r3Q4NaAUCKqN3RuzBFcLBUVhI9b6SJWZwlK4AFgej3AolnfwDR6k-oBE7ZNF6u2V8pfSoMrVCxlfOiBRHVTra1cJkLA4YX4FQGdzDUShHDFiH1UjXDnQOoiw9M6koS0uTLA6SpNvIJKk-JB4yqdKkgxyzYM2CZfNO4h0Qcl2rrOW-QAX3IJzDfeV3zDQIQs6lkrZgcQCy0QGLAywt0kgqLHqOFI3KnMa86M0AkUEzmpaitiQrlGW2hR060pbKa4vZGWsPiH6XXJelPpL68VHsqxJZtBzSkZb8X8r4Hf01ozySKi3rDIFFK2EtGjcuWPTh0rR1mVSvT-vXZku5vT79ZBnfGKEyvR8SNe_keXdpKdSOpIqWSktVSoVsumbTNRy0zCDXmvE5fWR8AWzWSghQS-XiSeKgQU9UvQcWrSFg0YnGWvkHEglaP7dD11AzPmc87leSRYhW54zPh8MLmgnof4_a6JMICZaHhDwKz2hOJNYJJ9MkFdaROjw7pAa_2EsUrWn9tc17zG53mcMZWYfw2_0vn-NJ8o_lv58pCiBJhN0nCRx0KZws0UvPla4Y5-eisdkaWne9vEvwZ4KH3wO8X395cdWcwJfLWzWfPvh3qRzshVQXfbDxzXOgvDJSudybPkNjGF_14jQvxvl9DkcEYRCsVLsSRxTYKql25G5HBFvousygEAcEAdbpCgo0SPGWuBmz6Uq9kMGgq40aHIBnsuCjQ6No-xXjHN50_L4SUPmcjmHEEweML5-Zj_EN4xtYa7K2KPfaOqJQ2hVe0rAjfLuhXpfoDRwnUkn3gu0VXBLjtFcXY4dbr4Y57lpQ7kLiBBo1-xANo98pdY1-x0dnBIwqzIRyMoWRdRmL1m0kD2cw2mVHYfLRFEafAnhPEiV3a9PzOE0BYKS776_I9mutFKUc6aBWGRqfrJoQSc4KQ2el_EwZmOjP0iSKtAAn99h5ulRvytBf0-W8YWYBTpgdOkgNCofkA2PGN51wnLdmqo1B5QAfMa2d2BL36BM74zPGN4XeI-Ob2qJhfEPQI4fkpz3SjNz3cR4n8YTxxfgFH1uD4kulKVIQ9GiUyxKHWh-N6FRB5-93PX3IoiXVHAZ9euq2jINTZAFymChegHADSBYtKe0sp94CWWbQNgkueAz6F8c4Cl-wa2rVjP3T6JTWRXHIJ_MplKJWaYEZ8fRO5VwGpvBVYdZxsgRXGBQZMB6FJIAS-0Z-xmc9sPc3CnwGhdXKEwxUHY7DPq7mxkPwiLynVcK0ec15HIUXNXtFox1oOG-C9TcnrXDRxvm3Jy_gwflmJ7wRiz4AD19FvJzRgPMOsx-Kzr9OAF74h_2zjUjRA6R6o_UmYj6w3lfTEeNzVZelV8X6DGqx2E6DS3aPIno7sRMFz5QWhZ2W6Asp9a9NpN4FoqgtHd6YUiGafKvHRNPngscX3KMN8H-Fj-javfWIT_4-4n8fcX_EJ38f8e95xP_ni8pFT8NH6br2EN2Q67Z6IZH7Esar6Dlzr5StnwukmJHqPYK0UNKOrhAKZIaiJMeTyjryaJ23BSFVrbVysukkofJTb6pS-cov6XpfDRzal2gDqrMOz8-kJmlBQPXkCq3ApkZWrulDGaxKmQoCdIW0sMVCHKQ2pCA_IC0U-gj3QPcZKcryCfTWojlg5neU1tbobX-5mm72PLVsyK2o0KM6b0u33U1D0J4Zua-0cc01YDig7RA8w7y7Kw93hr5dSEYmkPHD3bodG698_d6uaRZ09OMHdEv7pFLG5xtRWjyRdMjNHSAh_XaR6ewWMDv1bMzu0FD4dmc3jOpQvRg-B_fT2Tm3n_3M79IVG1niUmVLkxYkQrNywFXX6ht__Li-S5a_rn5O1h82y98-fk7iyd395_6u_EyypoPUQo3v7b9EKbOhljrCbSNAS9hfLhpO755-EftGu7PGNrNez2iMPjPKBxq4tEnVHuDBTh_9daEX-qSin9B9lNahwg5q2AIhQ5wNkAnOBn7R_iLbDpx_ezENANqOd-jSY3ZhN39OKe-0t5skL8WudVpoXaoloNiVCJegcuZpwF6jktXXDOXpxg91Sno6cdIu7xyKokiW5LVKndSqUadFR-TTu6GFVuTJfXuJz8g5n-98LNqLJm1Jan9wp5PUlS7esOgnHtr03p_LE_Ml0qHtkJq0P-xODq5aXU3QXFfP6Kd3weBo9S7spy-5cFMWtF7VUNG5aT4mzeQZfQ_aTj4vMKJ1N3OFGT_72nECIPMk6gxu3JlsTOM9qcwH1Eo7_2zgmZF7ffvOIOPznPHZQ5tGoX2Y0ZFTTXCCpEw9PK-tjmjtp9p9yjemOdt583-gJYBUKydVPWB2uP2mVun5VlTVfAgDKk_ZbAUfdSo6frQdV8IV462wqJodrTPdvmMqg5pTM859-bFoo3-LRx9ndy9offXkqaJu0yoFNgloywIfT_hVSnjnqnjuj14n98rplyaVOSRexCTp3JnxWZLQWUsSAu0PxCB7XS8zPtWuqt3rbSqv3-ZFmOcqPStNgU-HsgeP_aVm3obW677iS9FvLTu_I4eLybeDxVfBts_BBl2w64AwvwI4Sf8a_b2Ny8U1LrMXOnwTYBhcBUy_InaS_HSfJEn_MOz77o_p-wDDa4B58OPY8SqX0-B97hvya4BR_gOJfZXLyf8Fl7F4H-DkGuACfyCxr3Ip8H2A12L0NP2RrH2Vyyx_H-C1TBIHP1IEuspl-KL4eBMgvxbSTk-PfgSxr3M5-TO5vFgB3vt-F93UHDgjfctF2qad1f40yLdK4gAOaCzxIIiyVl_gia57KzjKsgSDvouyFekX0CpFuIdMt02im-w2yhbRQtzgbTgLF8Esivnkprid8Vhs54s5otiGIp1MMyHyHIN4Gi-m-RZv5C0P-CSIOQ9jPgsm48U042kaRlOxyMIgmLNJgHshy3FZHvZjbXY3vlt0u4gnQXhTii2W1v8sjHOFx66VxNl0fWNuac1oW-8smwSltM72KE660v-ezAs_XZ8_D8402kZlR22-wBHLsm0AdmaB7rG2f6gs8xGWFkdpIaSy45valLeFc5W_UPke6U66ot6OU733TycP3b9RZfR_MHWMbzzvlvFNI9vhlv83AAD__2HfV50">