dlerror does this: n = __asprintf (&buf, "%s%s%s: %s", result->objname, result->objname[0] == '\0' ? "" : ": ", _(result->errstring), strerror (result->errcode)); strerror is not thread-safe, and the could should assign errno and use %m.
As long as the errcode is in range the call is thread-safe.