1
0
Fork 0
mirror of https://github.com/tobast/libunwind-eh_elf.git synced 2024-11-29 02:07:39 +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:
Milian Wolff 2018-04-24 15:27:16 +02:00 committed by Milian Wolff
parent fba2ae7b2c
commit 2bb51aa4fd

View file

@ -932,7 +932,6 @@ find_reg_state (struct dwarf_cursor *c, dwarf_state_record_t *sr)
unsigned short index = -1; unsigned short index = -1;
if (cache) if (cache)
{ {
put_rs_cache (c->as, cache, &saved_mask);
if (rs) if (rs)
{ {
index = rs - cache->buckets; 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; cache->links[c->prev_rs].hint = index + 1;
c->prev_rs = index; c->prev_rs = index;
} }
put_rs_cache (c->as, cache, &saved_mask);
} }
if (ret < 0) if (ret < 0)
return ret; return ret;