The problem (in short):
- On Windows, gpgme calls gettext_use_utf8(1) to force gpgrt to use UTF-8 for the translated error messages.
- gpgrt stores the corresponding flag gt_use_utf8 in a thread-local storage object.
- If a new thread is created DllMain allocates a new thread-local storage object and initializes the flag to 0.
- If gpg_strerror_r is called from the new thread it returns the error message using native encoding.
I think new threads should inherit the value of the flag set for the main thread.
One could argue that this isn't a problem because translated error messages are only output by the main thread (in particular for GUI apps), but this assumption doesn't hold for debug output. And together with caching this makes Kleopatra show wrongly encoded error messages to its users. See T5960#188013 for more details.