mirror of
https://github.com/tobast/libunwind-eh_elf.git
synced 2024-11-25 08:37:38 +01:00
Fix data race on cache hints in find_reg_state
This can be reproduced by using libunwind from multiple threads with UNW_CACHE_GLOBAL cache policy, as e.g. happens by default or when libunwind wasn't build with --enable-per-thread-cache. The call to put_rs_cache unlocks the cache, but we used to access data that needs to be guarded still. So move the call to put_rs_cache down to protect the data properly. Fixes the following data race reported by TSAN: WARNING: ThreadSanitizer: data race (pid=16551) Read of size 2 at 0x7f7dda69ed7a by thread T2: #0 find_reg_state ../../src/dwarf/Gparser.c:939 (libunwind.so. 8+0x000000037254) #1 _ULx86_64_dwarf_step ../../src/dwarf/Gparser.c:958 (libunwind.so. 8+0x000000037543) #2 _ULx86_64_step ../../src/x86_64/Gstep.c:71 (libunwind.so. 8+0x000000021fdd) #3 trace_init_addr ../../src/x86_64/Gtrace.c:248 (libunwind.so. 8+0x0000000246cc) #4 trace_lookup ../../src/x86_64/Gtrace.c:330 (libunwind.so. 8+0x000000024be7) #5 _ULx86_64_tdep_trace ../../src/x86_64/Gtrace.c:447 (libunwind.so. 8+0x000000025058) #6 unw_backtrace ../../src/mi/backtrace.c:69 (libunwind.so. 8+0x00000001a6e7) Previous write of size 2 at 0x7f7dda69ed7a by thread T3: #0 find_reg_state ../../src/dwarf/Gparser.c:940 (libunwind.so. 8+0x000000037383) #1 _ULx86_64_dwarf_step ../../src/dwarf/Gparser.c:958 (libunwind.so. 8+0x000000037543) #2 _ULx86_64_step ../../src/x86_64/Gstep.c:71 (libunwind.so. 8+0x000000021fdd) #3 trace_init_addr ../../src/x86_64/Gtrace.c:248 (libunwind.so. 8+0x0000000246cc) #4 trace_lookup ../../src/x86_64/Gtrace.c:330 (libunwind.so. 8+0x000000024be7) #5 _ULx86_64_tdep_trace ../../src/x86_64/Gtrace.c:447 (libunwind.so. 8+0x000000025058) #6 unw_backtrace ../../src/mi/backtrace.c:69 (libunwind.so. 8+0x00000001a6e7) Location is global 'local_addr_space' of size 26296 at 0x7f7dda698c60 (libunwind.so.8+0x000000268d7a)
This commit is contained in:
parent
fba2ae7b2c
commit
2bb51aa4fd
1 changed files with 1 additions and 1 deletions
|
@ -932,7 +932,6 @@ find_reg_state (struct dwarf_cursor *c, dwarf_state_record_t *sr)
|
|||
unsigned short index = -1;
|
||||
if (cache)
|
||||
{
|
||||
put_rs_cache (c->as, cache, &saved_mask);
|
||||
if (rs)
|
||||
{
|
||||
index = rs - cache->buckets;
|
||||
|
@ -940,6 +939,7 @@ find_reg_state (struct dwarf_cursor *c, dwarf_state_record_t *sr)
|
|||
cache->links[c->prev_rs].hint = index + 1;
|
||||
c->prev_rs = index;
|
||||
}
|
||||
put_rs_cache (c->as, cache, &saved_mask);
|
||||
}
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
|
Loading…
Reference in a new issue