Skip to content

Commit

Permalink
Mark cs_* as thread local to avoid race condition in multithreads
Browse files Browse the repository at this point in the history
  • Loading branch information
wtdcode committed Jul 3, 2022
1 parent 68cc30d commit bdab894
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 27 deletions.
43 changes: 21 additions & 22 deletions cs.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,27 +285,26 @@ static const uint32_t all_arch = 0
#endif
;


#if defined(CAPSTONE_USE_SYS_DYN_MEM)
#if !defined(CAPSTONE_HAS_OSXKERNEL) && !defined(_KERNEL_MODE)
// default
cs_malloc_t cs_mem_malloc = malloc;
cs_calloc_t cs_mem_calloc = calloc;
cs_realloc_t cs_mem_realloc = realloc;
cs_free_t cs_mem_free = free;
thread_local cs_malloc_t cs_mem_malloc = malloc;
thread_local cs_calloc_t cs_mem_calloc = calloc;
thread_local cs_realloc_t cs_mem_realloc = realloc;
thread_local cs_free_t cs_mem_free = free;
#if defined(_WIN32_WCE)
cs_vsnprintf_t cs_vsnprintf = _vsnprintf;
thread_local cs_vsnprintf_t cs_vsnprintf = _vsnprintf;
#else
cs_vsnprintf_t cs_vsnprintf = vsnprintf;
thread_local cs_vsnprintf_t cs_vsnprintf = vsnprintf;
#endif // defined(_WIN32_WCE)

#elif defined(_KERNEL_MODE)
// Windows driver
cs_malloc_t cs_mem_malloc = cs_winkernel_malloc;
cs_calloc_t cs_mem_calloc = cs_winkernel_calloc;
cs_realloc_t cs_mem_realloc = cs_winkernel_realloc;
cs_free_t cs_mem_free = cs_winkernel_free;
cs_vsnprintf_t cs_vsnprintf = cs_winkernel_vsnprintf;
thread_local cs_malloc_t cs_mem_malloc = cs_winkernel_malloc;
thread_local cs_calloc_t cs_mem_calloc = cs_winkernel_calloc;
thread_local cs_realloc_t cs_mem_realloc = cs_winkernel_realloc;
thread_local cs_free_t cs_mem_free = cs_winkernel_free;
thread_local cs_vsnprintf_t cs_vsnprintf = cs_winkernel_vsnprintf;
#else
// OSX kernel
extern void* kern_os_malloc(size_t size);
Expand All @@ -317,19 +316,19 @@ static void* cs_kern_os_calloc(size_t num, size_t size)
return kern_os_malloc(num * size); // malloc bzeroes the buffer
}

cs_malloc_t cs_mem_malloc = kern_os_malloc;
cs_calloc_t cs_mem_calloc = cs_kern_os_calloc;
cs_realloc_t cs_mem_realloc = kern_os_realloc;
cs_free_t cs_mem_free = kern_os_free;
cs_vsnprintf_t cs_vsnprintf = vsnprintf;
thread_local cs_malloc_t cs_mem_malloc = kern_os_malloc;
thread_local cs_calloc_t cs_mem_calloc = cs_kern_os_calloc;
thread_local cs_realloc_t cs_mem_realloc = kern_os_realloc;
thread_local cs_free_t cs_mem_free = kern_os_free;
thread_local cs_vsnprintf_t cs_vsnprintf = vsnprintf;
#endif // !defined(CAPSTONE_HAS_OSXKERNEL) && !defined(_KERNEL_MODE)
#else
// User-defined
cs_malloc_t cs_mem_malloc = NULL;
cs_calloc_t cs_mem_calloc = NULL;
cs_realloc_t cs_mem_realloc = NULL;
cs_free_t cs_mem_free = NULL;
cs_vsnprintf_t cs_vsnprintf = NULL;
thread_local cs_malloc_t cs_mem_malloc = NULL;
thread_local cs_calloc_t cs_mem_calloc = NULL;
thread_local cs_realloc_t cs_mem_realloc = NULL;
thread_local cs_free_t cs_mem_free = NULL;
thread_local cs_vsnprintf_t cs_vsnprintf = NULL;

#endif // defined(CAPSTONE_USE_SYS_DYN_MEM)

Expand Down
21 changes: 16 additions & 5 deletions cs_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,22 @@ struct cs_struct {
// Returns a bool (0 or 1) whether big endian is enabled for a mode
#define MODE_IS_BIG_ENDIAN(mode) (((mode) & CS_MODE_BIG_ENDIAN) != 0)

extern cs_malloc_t cs_mem_malloc;
extern cs_calloc_t cs_mem_calloc;
extern cs_realloc_t cs_mem_realloc;
extern cs_free_t cs_mem_free;
extern cs_vsnprintf_t cs_vsnprintf;

#ifndef thread_local
#if defined (__GNUC__) || defined (__clang__)
#define thread_local __thread // prior to C11
#elif _MSC_VER
#define thread_local __declspec( thread ) // early msvc
#else
#define thread_local // failsafe
#endif
#endif

extern thread_local cs_malloc_t cs_mem_malloc;
extern thread_local cs_calloc_t cs_mem_calloc;
extern thread_local cs_realloc_t cs_mem_realloc;
extern thread_local cs_free_t cs_mem_free;
extern thread_local cs_vsnprintf_t cs_vsnprintf;

// By defining CAPSTONE_DEBUG assertions can be used.
// For any release build CAPSTONE_DEBUG has to be undefined.
Expand Down

0 comments on commit bdab894

Please sign in to comment.