On 07.11.2012 16:54, Matthias Schwarzott wrote:
Hi!
I wonder if it would be good to have valgrind remember the names of the
threads.
Here is a first implementation of this change.
It just enhances the struct ThreadState by a char array thread_name.
The handler of prctl writes its argument there.
For the first thread it is initialized to "main" (without valgrind there
is the name of the executable by default, how could I get this).
pp_Error prints Errors like this (if thread name is there):
Thread 2 abcdxyz01234567:
gdbserver appends it at the end for the qThreadExtraInfo query.
(gdb) info threads
Id Target Id Frame
* 2 Thread 30698 (tid 2 VgTs_Runnable abcdxyz01234567)
0x00000000004009aa in child_fn (arg=0x0) at threadname.c:32
1 Thread 30679 (tid 1 VgTs_Yielding main) 0x00000034cfae88d1 in
clone () from /lib64/libc.so.6
The testcase I started to write is also included.
Regards
Matthias
commit 56074382acdf0eb5f77c08aaec7b65a877658823
Author: Matthias Schwarzott <z...@gentoo.org>
Date: Tue Oct 30 20:39:21 2012 +0100
set thread name
diff --git a/coregrind/m_errormgr.c b/coregrind/m_errormgr.c
index b4fec57..066056b 100644
--- a/coregrind/m_errormgr.c
+++ b/coregrind/m_errormgr.c
@@ -603,7 +603,12 @@ static void pp_Error ( Error* err, Bool allow_db_attach, Bool xml )
if (VG_(tdict).tool_show_ThreadIDs_for_errors
&& err->tid > 0 && err->tid != last_tid_printed) {
- VG_(umsg)("Thread %d:\n", err->tid );
+ ThreadState* tst = VG_(get_ThreadState)(err->tid);
+ if (tst->thread_name[0]) {
+ VG_(umsg)("Thread %d %s:\n", err->tid, VG_(get_ThreadState)(err->tid)->thread_name);
+ } else {
+ VG_(umsg)("Thread %d:\n", err->tid );
+ }
last_tid_printed = err->tid;
}
diff --git a/coregrind/m_gdbserver/server.c b/coregrind/m_gdbserver/server.c
index 5dcb139..277ba59 100644
--- a/coregrind/m_gdbserver/server.c
+++ b/coregrind/m_gdbserver/server.c
@@ -499,9 +499,16 @@ void handle_query (char *arg_own_buf, int *new_packet_len_p)
if (ti != NULL) {
tst = (ThreadState *) inferior_target_data (ti);
/* Additional info is the tid and the thread status. */
+ if (tst->thread_name[0]) {
+ VG_(snprintf) (status, sizeof(status), "tid %d %s %s",
+ tst->tid,
+ VG_(name_of_ThreadStatus)(tst->status),
+ tst->thread_name);
+ } else {
VG_(snprintf) (status, sizeof(status), "tid %d %s",
tst->tid,
VG_(name_of_ThreadStatus)(tst->status));
+ }
hexify (arg_own_buf, status, strlen(status));
return;
} else {
diff --git a/coregrind/m_scheduler/scheduler.c b/coregrind/m_scheduler/scheduler.c
index ef41c64..56feac2 100644
--- a/coregrind/m_scheduler/scheduler.c
+++ b/coregrind/m_scheduler/scheduler.c
@@ -236,6 +236,7 @@ ThreadId VG_(alloc_ThreadState) ( void )
if (VG_(threads)[i].status == VgTs_Empty) {
VG_(threads)[i].status = VgTs_Init;
VG_(threads)[i].exitreason = VgSrc_None;
+ VG_(threads)[i].thread_name[0] = 0;
return i;
}
}
@@ -614,6 +615,7 @@ ThreadId VG_(scheduler_init_phase1) ( void )
}
tid_main = VG_(alloc_ThreadState)();
+ VG_(strncpy)(VG_(threads)[tid_main].thread_name, "main", sizeof(VG_(threads)[tid_main].thread_name));
/* Bleh. Unfortunately there are various places in the system that
assume that the main thread has a ThreadId of 1.
diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
index 7c94bd5..6cde946 100644
--- a/coregrind/m_syswrap/syswrap-linux.c
+++ b/coregrind/m_syswrap/syswrap-linux.c
@@ -939,6 +939,13 @@ POST(sys_prctl)
case VKI_PR_GET_FPEXC:
POST_MEM_WRITE(ARG2, sizeof(Int));
break;
+ case VKI_PR_SET_NAME:
+ {
+ ThreadState* tst = VG_(get_ThreadState)(tid);
+ VG_(strncpy)(tst->thread_name, (char*)ARG2, 16);
+ tst->thread_name[16] = 0;
+ }
+ break;
case VKI_PR_GET_NAME:
POST_MEM_WRITE(ARG2, VKI_TASK_COMM_LEN);
break;
diff --git a/coregrind/pub_core_threadstate.h b/coregrind/pub_core_threadstate.h
index 0bd9927..73ee947 100644
--- a/coregrind/pub_core_threadstate.h
+++ b/coregrind/pub_core_threadstate.h
@@ -353,6 +353,8 @@ typedef struct {
/* Per-thread jmp_buf to resume scheduler after a signal */
Bool sched_jmpbuf_valid;
VG_MINIMAL_JMP_BUF(sched_jmpbuf);
+
+ char thread_name[17];
}
ThreadState;
diff --git a/memcheck/tests/Makefile.am b/memcheck/tests/Makefile.am
index cf1d5cc..4bfce22 100644
--- a/memcheck/tests/Makefile.am
+++ b/memcheck/tests/Makefile.am
@@ -228,7 +228,8 @@ EXTRA_DIST = \
wrap8.vgtest wrap8.stdout.exp wrap8.stderr.exp \
wrap8.stdout.exp2 wrap8.stderr.exp2 \
writev1.stderr.exp writev1.vgtest \
- xml1.stderr.exp xml1.stdout.exp xml1.vgtest xml1.stderr.exp-s390x-mvc
+ xml1.stderr.exp xml1.stdout.exp xml1.vgtest xml1.stderr.exp-s390x-mvc \
+ threadname.vgtest
check_PROGRAMS = \
accounting \
@@ -296,7 +297,8 @@ check_PROGRAMS = \
vcpu_fbench vcpu_fnfns \
xml1 \
wrap1 wrap2 wrap3 wrap4 wrap5 wrap6 wrap7 wrap7so.so wrap8 \
- writev1
+ writev1 \
+ threadname
if DWARF4
check_PROGRAMS += dw4
@@ -323,6 +325,7 @@ dw4_CFLAGS = $(AM_CFLAGS) -gdwarf-4 -fdebug-types-section
err_disable3_LDADD = -lpthread
err_disable4_LDADD = -lpthread
+threadname_LDADD = -lpthread
error_counts_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNINITIALIZED@
diff --git a/memcheck/tests/threadname.c b/memcheck/tests/threadname.c
new file mode 100644
index 0000000..b8366de
--- /dev/null
+++ b/memcheck/tests/threadname.c
@@ -0,0 +1,54 @@
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <pthread.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/prctl.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <assert.h>
+
+void* child_fn ( void* arg )
+{
+ pthread_setname_np(pthread_self(), "");
+ pthread_setname_np(pthread_self(), "a");
+ pthread_setname_np(pthread_self(), "ab");
+ pthread_setname_np(pthread_self(), "abc");
+ pthread_setname_np(pthread_self(), "abcd");
+ pthread_setname_np(pthread_self(), "abcdx");
+ pthread_setname_np(pthread_self(), "abcdxy");
+ pthread_setname_np(pthread_self(), "abcdxyz");
+ pthread_setname_np(pthread_self(), "abcdxyz0");
+ pthread_setname_np(pthread_self(), "abcdxyz01");
+ pthread_setname_np(pthread_self(), "abcdxyz012");
+ pthread_setname_np(pthread_self(), "abcdxyz0123");
+ pthread_setname_np(pthread_self(), "abcdxyz01234");
+ pthread_setname_np(pthread_self(), "abcdxyz012345");
+ pthread_setname_np(pthread_self(), "abcdxyz0123456");
+ pthread_setname_np(pthread_self(), "abcdxyz01234567");
+ pthread_setname_np(pthread_self(), "abcdxyz012345678");
+ pthread_setname_np(pthread_self(), "abcdxyz0123456789");
+ int* m = malloc(sizeof(int));
+ m[2]=0;
+ free(m);
+ return NULL;
+}
+
+int main(int argc, const char** argv)
+{
+ int r;
+ pthread_t child;
+ int* o = malloc(sizeof(int));
+ o[1]=0;
+ free(o);
+ r = pthread_create(&child, NULL, child_fn, NULL);
+ assert(!r);
+ sleep(1);
+ r = pthread_join(child, NULL);
+ assert(!r);
+ o = malloc(sizeof(int));
+ o[1]=0;
+ free(o);
+ return 0;
+}
+
diff --git a/memcheck/tests/threadname.vgtest b/memcheck/tests/threadname.vgtest
new file mode 100644
index 0000000..01b0d43
--- /dev/null
+++ b/memcheck/tests/threadname.vgtest
@@ -0,0 +1 @@
+prog: threadname
------------------------------------------------------------------------------
Monitor your physical, virtual and cloud infrastructure from a single
web console. Get in-depth insight into apps, servers, databases, vmware,
SAP, cloud infrastructure, etc. Download 30-day Free Trial.
Pricing starts from $795 for 25 servers or applications!
http://p.sf.net/sfu/zoho_dev2dev_nov
_______________________________________________
Valgrind-users mailing list
Valgrind-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/valgrind-users