Individual debuginfod_client objects and their underlying CURLM handles should not be used concurrently during calls to __libdwfl_debuginfod_find_debuginfo and __libdwfl_debuginfod_find_executable.
Add a mutex field to struct Dwfl and synchronize calls to __libdwfl_debuginfod_find_*. Signed-off-by: Aaron Merey <[email protected]> --- libdwfl/debuginfod-client.c | 9 +++++++-- libdwfl/dwfl_begin.c | 2 ++ libdwfl/dwfl_end.c | 1 + libdwfl/libdwflP.h | 1 + 4 files changed, 11 insertions(+), 2 deletions(-) diff --git a/libdwfl/debuginfod-client.c b/libdwfl/debuginfod-client.c index 882a5eff..4b457da4 100644 --- a/libdwfl/debuginfod-client.c +++ b/libdwfl/debuginfod-client.c @@ -49,7 +49,7 @@ static void __libdwfl_debuginfod_init (void); static pthread_once_t init_control = PTHREAD_ONCE_INIT; -/* NB: this is slightly thread-unsafe */ +/* A per-Dwfl lock must be held when calling this function. */ debuginfod_client * dwfl_get_debuginfod_client (Dwfl *dwfl) @@ -77,10 +77,12 @@ __libdwfl_debuginfod_find_executable (Dwfl *dwfl, int fd = -1; if (build_id_len > 0) { + mutex_lock (dwfl->lock); debuginfod_client *c = INTUSE (dwfl_get_debuginfod_client) (dwfl); if (c != NULL) fd = (*fp_debuginfod_find_executable) (c, build_id_bits, build_id_len, NULL); + mutex_unlock (dwfl->lock); } return fd; @@ -94,10 +96,12 @@ __libdwfl_debuginfod_find_debuginfo (Dwfl *dwfl, int fd = -1; if (build_id_len > 0) { + mutex_lock (dwfl->lock); debuginfod_client *c = INTUSE (dwfl_get_debuginfod_client) (dwfl); if (c != NULL) fd = (*fp_debuginfod_find_debuginfo) (c, build_id_bits, build_id_len, NULL); + mutex_unlock (dwfl->lock); } return fd; @@ -111,7 +115,8 @@ __libdwfl_debuginfod_end (debuginfod_client *c) } /* Try to get the libdebuginfod library functions. - Only needs to be called once from dwfl_get_debuginfod_client. */ + Only needs to be called once from dwfl_get_debuginfod_client. + A per-Dwfl lock must be held when calling this function. */ static void __libdwfl_debuginfod_init (void) { diff --git a/libdwfl/dwfl_begin.c b/libdwfl/dwfl_begin.c index b03f5cf4..71947851 100644 --- a/libdwfl/dwfl_begin.c +++ b/libdwfl/dwfl_begin.c @@ -50,6 +50,8 @@ dwfl_begin (const Dwfl_Callbacks *callbacks) dwfl->offline_next_address = OFFLINE_REDZONE; } + mutex_init (dwfl->lock); + return dwfl; } INTDEF (dwfl_begin) diff --git a/libdwfl/dwfl_end.c b/libdwfl/dwfl_end.c index d9cf569b..594051f0 100644 --- a/libdwfl/dwfl_end.c +++ b/libdwfl/dwfl_end.c @@ -53,6 +53,7 @@ dwfl_end (Dwfl *dwfl) free (dwfl->lookup_module); free (dwfl->lookup_segndx); free (dwfl->sysroot); + mutex_fini (dwfl->lock); Dwfl_Module *next = dwfl->modulelist; while (next != NULL) diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h index a5d88d60..341c0527 100644 --- a/libdwfl/libdwflP.h +++ b/libdwfl/libdwflP.h @@ -141,6 +141,7 @@ struct Dwfl struct Dwfl_User_Core *user_core; char *sysroot; /* sysroot, or NULL to search standard system paths */ + mutex_define (, lock); /* Synchronize concurrent access. */ }; #define OFFLINE_REDZONE 0x10000 -- 2.51.1
