Hi Aaron,
On Fri, 2025-12-19 at 17:39 -0500, Aaron Merey wrote:
> 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 to serialize calls to
> __libdwfl_debuginfod_find_*.
>
> Signed-off-by: Aaron Merey <[email protected]>
> ---
>
> v3 changes: In libdwfl.h, add the following to the comment for
> dwfl_get_debuginfod_client:
>
> The returned debuginfod-client handle must not be used at the same time as
> any libdwfl function taking the client's associated DWFL as an argument.
Yes, that is a good comment. So basically you have to use the handle
before you start using the Dwfl itself.
Locking itself looks correct.
> -/* NB: this is slightly thread-unsafe */
> +/* dwfl->debuginfod_lock must be held when calling this function. */
>
> debuginfod_client *
> dwfl_get_debuginfod_client (Dwfl *dwfl)
OK. When calling the function and calling a method on the handle.
> @@ -77,10 +77,12 @@ __libdwfl_debuginfod_find_executable (Dwfl *dwfl,
> int fd = -1;
> if (build_id_len > 0)
> {
> + mutex_lock (dwfl->debuginfod_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->debuginfod_lock);
> }
>
> return fd;
Good.
> @@ -94,10 +96,12 @@ __libdwfl_debuginfod_find_debuginfo (Dwfl *dwfl,
> int fd = -1;
> if (build_id_len > 0)
> {
> + mutex_lock (dwfl->debuginfod_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->debuginfod_lock);
> }
>
> return fd;
Same.
> diff --git a/libdwfl/dwfl_begin.c b/libdwfl/dwfl_begin.c
> index b03f5cf4..835de8e3 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->debuginfod_lock);
> +
> return dwfl;
> }
> INTDEF (dwfl_begin)
OK, begin inits the lock.
> diff --git a/libdwfl/dwfl_end.c b/libdwfl/dwfl_end.c
> index d9cf569b..c82d83fb 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->debuginfod_lock);
>
> Dwfl_Module *next = dwfl->modulelist;
> while (next != NULL)
And end finis it.
> diff --git a/libdwfl/libdwfl.h b/libdwfl/libdwfl.h
> index 90523283..e94dacdf 100644
> --- a/libdwfl/libdwfl.h
> +++ b/libdwfl/libdwfl.h
> @@ -835,6 +835,9 @@ int dwfl_frame_reg (Dwfl_Frame *state, unsigned regno,
> Dwarf_Word *val)
> When the client connection has not yet been initialized, it will be done
> on the
> first call to this function. If elfutils is compiled without support for
> debuginfod,
> NULL will be returned.
> +
> + The returned debuginfod-client handle must not be used at the same time as
> + any libdwfl function taking the client's associated DWFL as an argument.
> */
> extern debuginfod_client *dwfl_get_debuginfod_client (Dwfl *dwfl);
Ack, as above.
>
> diff --git a/libdwfl/libdwflP.h b/libdwfl/libdwflP.h
> index a5d88d60..6e394c26 100644
> --- a/libdwfl/libdwflP.h
> +++ b/libdwfl/libdwflP.h
> @@ -141,6 +141,9 @@ struct Dwfl
> struct Dwfl_User_Core *user_core;
> char *sysroot; /* sysroot, or NULL to search standard system
> paths */
> +
> + /* Serialize debuginfod_client usage. */
> + mutex_define (, debuginfod_lock);
> };
OK, new lock field in Dwfl struct.
Thanks,
Mark