#include "clinic/traceback.c.h"
+
+#ifdef MS_WINDOWS
+typedef HRESULT (WINAPI *PF_GET_THREAD_DESCRIPTION)(HANDLE, PCWSTR*);
+static PF_GET_THREAD_DESCRIPTION pGetThreadDescription = NULL;
+#endif
+
+
static PyObject *
tb_create_raw(PyTracebackObject *next, PyFrameObject *frame, int lasti,
int lineno)
# endif
#endif
-/* Write the thread identifier into the file 'fd': "Current thread 0xHHHH:\" if
- is_current is true, "Thread 0xHHHH:\n" otherwise.
-
- This function is signal safe. */
+// Write the thread name
static void
-write_thread_id(int fd, PyThreadState *tstate, int is_current)
+write_thread_name(int fd, PyThreadState *tstate)
{
- if (is_current)
- PUTS(fd, "Current thread 0x");
- else
- PUTS(fd, "Thread 0x");
- _Py_DumpHexadecimal(fd,
- tstate->thread_id,
- sizeof(unsigned long) * 2);
-
- // Write the thread name
+#ifndef MS_WINDOWS
#if defined(HAVE_PTHREAD_GETNAME_NP) || defined(HAVE_PTHREAD_GET_NAME_NP)
char name[100];
pthread_t thread = (pthread_t)tstate->thread_id;
}
}
#endif
+#else
+ // Windows implementation
+ if (pGetThreadDescription == NULL) {
+ return;
+ }
+
+ HANDLE thread = OpenThread(THREAD_QUERY_LIMITED_INFORMATION, FALSE, tstate->thread_id);
+ if (thread == NULL) {
+ return;
+ }
+
+ wchar_t *wname;
+ HRESULT hr = pGetThreadDescription(thread, &wname);
+ if (!FAILED(hr)) {
+ char *name = _Py_EncodeLocaleRaw(wname, NULL);
+ if (name != NULL) {
+ size_t len = strlen(name);
+ if (len) {
+ PUTS(fd, " [");
+ (void)_Py_write_noraise(fd, name, len);
+ PUTS(fd, "]");
+ }
+ PyMem_RawFree(name);
+ }
+ LocalFree(wname);
+ }
+ CloseHandle(thread);
+#endif
+}
+
+
+/* Write the thread identifier into the file 'fd': "Current thread 0xHHHH:\" if
+ is_current is true, "Thread 0xHHHH:\n" otherwise.
+
+ This function is signal safe (except on Windows). */
+
+static void
+write_thread_id(int fd, PyThreadState *tstate, int is_current)
+{
+ if (is_current)
+ PUTS(fd, "Current thread 0x");
+ else
+ PUTS(fd, "Thread 0x");
+ _Py_DumpHexadecimal(fd,
+ tstate->thread_id,
+ sizeof(unsigned long) * 2);
+
+ write_thread_name(fd, tstate);
PUTS(fd, " (most recent call first):\n");
}
(void)backtrace(callstack, 1);
#endif
}
+
+
+void
+_Py_DumpTraceback_Init(void)
+{
+#ifdef MS_WINDOWS
+ if (pGetThreadDescription != NULL) {
+ return;
+ }
+
+ HMODULE kernelbase = GetModuleHandleW(L"kernelbase.dll");
+ if (kernelbase != NULL) {
+ pGetThreadDescription = (PF_GET_THREAD_DESCRIPTION)GetProcAddress(
+ kernelbase, "GetThreadDescription");
+ }
+#endif
+}