|
From: <sv...@va...> - 2013-09-16 17:09:10
|
Author: florian
Date: Mon Sep 16 17:08:50 2013
New Revision: 13553
Log:
Intercept prctl(PR_SET_NAME, name) and store the thread name so it
can be used in error messages. That should be helpful when debugging
multithreaded applications.
Patch by Matthias Schwarzott <zz...@ge...> with some minor
modifications. Fixes BZ 322254.
Added:
trunk/memcheck/tests/threadname.c
trunk/memcheck/tests/threadname.stderr.exp
trunk/memcheck/tests/threadname.vgtest
trunk/memcheck/tests/threadname_xml.stderr.exp
trunk/memcheck/tests/threadname_xml.vgtest
Modified:
trunk/NEWS
trunk/coregrind/m_errormgr.c
trunk/coregrind/m_gdbserver/server.c
trunk/coregrind/m_scheduler/scheduler.c
trunk/coregrind/m_syswrap/syswrap-linux.c
trunk/coregrind/pub_core_threadstate.h
trunk/docs/internals/xml-output-protocol4.txt
trunk/memcheck/tests/ (props changed)
trunk/memcheck/tests/Makefile.am
Modified: trunk/NEWS
==============================================================================
--- trunk/NEWS (original)
+++ trunk/NEWS Mon Sep 16 17:08:50 2013
@@ -464,6 +464,9 @@
321969 ppc32 and ppc64 don't support [lf]setxattr
FIXED r13449
+322254 Show threadname together with tid if set by application
+ FIXED r13553
+
322368 Assertion failure in wqthread_hijack under OS X 10.8
FIXED 13523
Modified: trunk/coregrind/m_errormgr.c
==============================================================================
--- trunk/coregrind/m_errormgr.c (original)
+++ trunk/coregrind/m_errormgr.c Mon Sep 16 17:08:50 2013
@@ -591,6 +591,10 @@
VG_(printf_xml)("<error>\n");
VG_(printf_xml)(" <unique>0x%x</unique>\n", err->unique);
VG_(printf_xml)(" <tid>%d</tid>\n", err->tid);
+ ThreadState* tst = VG_(get_ThreadState)(err->tid);
+ if (tst->thread_name) {
+ VG_(printf_xml)(" <threadname>%s</threadname>\n", tst->thread_name);
+ }
/* actually print it */
VG_TDICT_CALL( tool_pp_Error, err );
@@ -608,7 +612,12 @@
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) {
+ VG_(umsg)("Thread %d %s:\n", err->tid, tst->thread_name );
+ } else {
+ VG_(umsg)("Thread %d:\n", err->tid );
+ }
last_tid_printed = err->tid;
}
Modified: trunk/coregrind/m_gdbserver/server.c
==============================================================================
--- trunk/coregrind/m_gdbserver/server.c (original)
+++ trunk/coregrind/m_gdbserver/server.c Mon Sep 16 17:08:50 2013
@@ -588,10 +588,18 @@
ti = gdb_id_to_thread (gdb_id);
if (ti != NULL) {
tst = (ThreadState *) inferior_target_data (ti);
- /* Additional info is the tid and the thread status. */
- VG_(snprintf) (status, sizeof(status), "tid %d %s",
- tst->tid,
- VG_(name_of_ThreadStatus)(tst->status));
+ /* Additional info is the tid, the thread status and the thread's
+ name, if any. */
+ if (tst->thread_name) {
+ 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 {
Modified: trunk/coregrind/m_scheduler/scheduler.c
==============================================================================
--- trunk/coregrind/m_scheduler/scheduler.c (original)
+++ trunk/coregrind/m_scheduler/scheduler.c Mon Sep 16 17:08:50 2013
@@ -238,6 +238,7 @@
if (VG_(threads)[i].status == VgTs_Empty) {
VG_(threads)[i].status = VgTs_Init;
VG_(threads)[i].exitreason = VgSrc_None;
+ VG_(threads)[i].thread_name = NULL;
return i;
}
}
@@ -616,6 +617,7 @@
VG_(threads)[i].client_stack_szB = 0;
VG_(threads)[i].client_stack_highest_word = (Addr)NULL;
VG_(threads)[i].err_disablement_level = 0;
+ VG_(threads)[i].thread_name = NULL;
}
tid_main = VG_(alloc_ThreadState)();
Modified: trunk/coregrind/m_syswrap/syswrap-linux.c
==============================================================================
--- trunk/coregrind/m_syswrap/syswrap-linux.c (original)
+++ trunk/coregrind/m_syswrap/syswrap-linux.c Mon Sep 16 17:08:50 2013
@@ -946,6 +946,18 @@
case VKI_PR_GET_ENDIAN:
POST_MEM_WRITE(ARG2, sizeof(Int));
break;
+ case VKI_PR_SET_NAME:
+ {
+ const HChar* new_name = (const HChar*) ARG2;
+ if (new_name) { // Paranoia
+ ThreadState* tst = VG_(get_ThreadState)(tid);
+
+ /* Don't bother reusing the memory. This is a rare event. */
+ tst->thread_name =
+ VG_(arena_strdup)(VG_AR_CORE, "syswrap.prctl", new_name);
+ }
+ }
+ break;
}
}
Modified: trunk/coregrind/pub_core_threadstate.h
==============================================================================
--- trunk/coregrind/pub_core_threadstate.h (original)
+++ trunk/coregrind/pub_core_threadstate.h Mon Sep 16 17:08:50 2013
@@ -357,6 +357,9 @@
/* Per-thread jmp_buf to resume scheduler after a signal */
Bool sched_jmpbuf_valid;
VG_MINIMAL_JMP_BUF(sched_jmpbuf);
+
+ /* This thread's name. NULL, if no name. */
+ HChar *thread_name;
}
ThreadState;
Modified: trunk/docs/internals/xml-output-protocol4.txt
==============================================================================
--- trunk/docs/internals/xml-output-protocol4.txt (original)
+++ trunk/docs/internals/xml-output-protocol4.txt Mon Sep 16 17:08:50 2013
@@ -408,6 +408,7 @@
<error>
<unique>HEX64</unique>
<tid>INT</tid>
+ <threadname>NAME</threadname> if set
<kind>KIND</kind>
(either WHAT or XWHAT)
@@ -428,6 +429,10 @@
is arbitrary but may be used to determine which threads produced
which errors (at least, the first instance of each error).
+* The <threadname> tag identifies the name of the thread if it was
+ set by the client application. If no name was set, the tag is
+ omitted.
+
* The <kind> tag specifies one of a small number of fixed error types,
so that GUIs may roughly categorise errors by type if they want.
The tags themselves are tool-specific and are defined further
Modified: trunk/memcheck/tests/Makefile.am
==============================================================================
--- trunk/memcheck/tests/Makefile.am (original)
+++ trunk/memcheck/tests/Makefile.am Mon Sep 16 17:08:50 2013
@@ -260,7 +260,10 @@
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 threadname.stdout.exp threadname.stderr.exp \
+ threadname_xml.vgtest threadname_xml.stdout.exp \
+ threadname_xml.stderr.exp
check_PROGRAMS = \
accounting \
@@ -335,7 +338,8 @@
wcs \
xml1 \
wrap1 wrap2 wrap3 wrap4 wrap5 wrap6 wrap7 wrap7so.so wrap8 \
- writev1
+ writev1 \
+ threadname
if DWARF4
check_PROGRAMS += dw4
@@ -367,6 +371,7 @@
err_disable3_LDADD = -lpthread
err_disable4_LDADD = -lpthread
thread_alloca_LDADD = -lpthread
+threadname_LDADD = -lpthread
error_counts_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNINITIALIZED@
Added: trunk/memcheck/tests/threadname.c
==============================================================================
--- trunk/memcheck/tests/threadname.c (added)
+++ trunk/memcheck/tests/threadname.c Mon Sep 16 17:08:50 2013
@@ -0,0 +1,80 @@
+//#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>
+
+static pthread_t children[3];
+
+void bad_things(int offset)
+{
+ char* m = malloc(sizeof(char)*offset);
+ m[offset] = 0;
+ free(m);
+}
+
+void* child_fn_2 ( void* arg )
+{
+ const char* threadname = "012345678901234";
+
+ pthread_setname_np(pthread_self(), threadname);
+
+ bad_things(4);
+
+ return NULL;
+}
+
+void* child_fn_1 ( void* arg )
+{
+ const char* threadname = "try1";
+ int r;
+
+ pthread_setname_np(pthread_self(), threadname);
+
+ bad_things(3);
+
+ r = pthread_create(&children[2], NULL, child_fn_2, NULL);
+ assert(!r);
+
+ r = pthread_join(children[2], NULL);
+ assert(!r);
+
+ return NULL;
+}
+
+void* child_fn_0 ( void* arg )
+{
+ int r;
+
+ bad_things(2);
+
+ r = pthread_create(&children[1], NULL, child_fn_1, NULL);
+ assert(!r);
+
+ r = pthread_join(children[1], NULL);
+ assert(!r);
+
+ return NULL;
+}
+
+int main(int argc, const char** argv)
+{
+ int r;
+
+ bad_things(1);
+
+ r = pthread_create(&children[0], NULL, child_fn_0, NULL);
+ assert(!r);
+
+ r = pthread_join(children[0], NULL);
+ assert(!r);
+
+ bad_things(5);
+
+ return 0;
+}
+
Added: trunk/memcheck/tests/threadname.stderr.exp
==============================================================================
--- trunk/memcheck/tests/threadname.stderr.exp (added)
+++ trunk/memcheck/tests/threadname.stderr.exp Mon Sep 16 17:08:50 2013
@@ -0,0 +1,50 @@
+Invalid write of size 1
+ at 0x........: bad_things (threadname.c:16)
+ by 0x........: main (threadname.c:68)
+ Address 0x........ is 0 bytes after a block of size 1 alloc'd
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: bad_things (threadname.c:15)
+ by 0x........: main (threadname.c:68)
+
+Thread 2:
+Invalid write of size 1
+ at 0x........: bad_things (threadname.c:16)
+ by 0x........: child_fn_0 (threadname.c:53)
+ ...
+ Address 0x........ is 0 bytes after a block of size 2 alloc'd
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: bad_things (threadname.c:15)
+ by 0x........: child_fn_0 (threadname.c:53)
+ ...
+
+Thread 3 try1:
+Invalid write of size 1
+ at 0x........: bad_things (threadname.c:16)
+ by 0x........: child_fn_1 (threadname.c:38)
+ ...
+ Address 0x........ is 0 bytes after a block of size 3 alloc'd
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: bad_things (threadname.c:15)
+ by 0x........: child_fn_1 (threadname.c:38)
+ ...
+
+Thread 4 012345678901234:
+Invalid write of size 1
+ at 0x........: bad_things (threadname.c:16)
+ by 0x........: child_fn_2 (threadname.c:26)
+ ...
+ Address 0x........ is 0 bytes after a block of size 4 alloc'd
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: bad_things (threadname.c:15)
+ by 0x........: child_fn_2 (threadname.c:26)
+ ...
+
+Thread 1:
+Invalid write of size 1
+ at 0x........: bad_things (threadname.c:16)
+ by 0x........: main (threadname.c:76)
+ Address 0x........ is 0 bytes after a block of size 5 alloc'd
+ at 0x........: malloc (vg_replace_malloc.c:...)
+ by 0x........: bad_things (threadname.c:15)
+ by 0x........: main (threadname.c:76)
+
Added: trunk/memcheck/tests/threadname.vgtest
==============================================================================
--- trunk/memcheck/tests/threadname.vgtest (added)
+++ trunk/memcheck/tests/threadname.vgtest Mon Sep 16 17:08:50 2013
@@ -0,0 +1,2 @@
+prog: threadname
+vgopts: -q
Added: trunk/memcheck/tests/threadname_xml.stderr.exp
==============================================================================
--- trunk/memcheck/tests/threadname_xml.stderr.exp (added)
+++ trunk/memcheck/tests/threadname_xml.stderr.exp Mon Sep 16 17:08:50 2013
@@ -0,0 +1,373 @@
+<?xml version="1.0"?>
+
+<valgrindoutput>
+
+<protocolversion>4</protocolversion>
+<protocoltool>memcheck</protocoltool>
+
+<preamble>
+ <line>...</line>
+ <line>...</line>
+ <line>...</line>
+ <line>...</line>
+</preamble>
+
+<pid>...</pid>
+<ppid>...</ppid>
+<tool>memcheck</tool>
+
+<args>
+ <vargv>...</vargv>
+ <argv>
+ <exe>./threadname</exe>
+ </argv>
+</args>
+
+<status>
+ <state>RUNNING</state>
+ <time>...</time>
+</status>
+
+<error>
+ <unique>0x........</unique>
+ <tid>...</tid>
+ <kind>InvalidWrite</kind>
+ <what>Invalid write of size 1</what>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>bad_things</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ <auxwhat>Address 0x........ is 0 bytes after a block of size 1 alloc'd</auxwhat>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>malloc</fn>
+ <dir>...</dir>
+ <file>vg_replace_malloc.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>bad_things</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+</error>
+
+<error>
+ <unique>0x........</unique>
+ <tid>...</tid>
+ <kind>InvalidWrite</kind>
+ <what>Invalid write of size 1</what>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>bad_things</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>child_fn_0</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>start_thread</fn>
+ <dir>...</dir>
+ <file>pthread_create.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ <auxwhat>Address 0x........ is 0 bytes after a block of size 2 alloc'd</auxwhat>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>malloc</fn>
+ <dir>...</dir>
+ <file>vg_replace_malloc.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>bad_things</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>child_fn_0</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>start_thread</fn>
+ <dir>...</dir>
+ <file>pthread_create.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+</error>
+
+<error>
+ <unique>0x........</unique>
+ <tid>...</tid>
+ <threadname>try1</threadname>
+ <kind>InvalidWrite</kind>
+ <what>Invalid write of size 1</what>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>bad_things</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>child_fn_1</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>start_thread</fn>
+ <dir>...</dir>
+ <file>pthread_create.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ <auxwhat>Address 0x........ is 0 bytes after a block of size 3 alloc'd</auxwhat>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>malloc</fn>
+ <dir>...</dir>
+ <file>vg_replace_malloc.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>bad_things</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>child_fn_1</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>start_thread</fn>
+ <dir>...</dir>
+ <file>pthread_create.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+</error>
+
+<error>
+ <unique>0x........</unique>
+ <tid>...</tid>
+ <threadname>012345678901234</threadname>
+ <kind>InvalidWrite</kind>
+ <what>Invalid write of size 1</what>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>bad_things</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>child_fn_2</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>start_thread</fn>
+ <dir>...</dir>
+ <file>pthread_create.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ <auxwhat>Address 0x........ is 0 bytes after a block of size 4 alloc'd</auxwhat>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>malloc</fn>
+ <dir>...</dir>
+ <file>vg_replace_malloc.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>bad_things</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>child_fn_2</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>start_thread</fn>
+ <dir>...</dir>
+ <file>pthread_create.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+</error>
+
+<error>
+ <unique>0x........</unique>
+ <tid>...</tid>
+ <kind>InvalidWrite</kind>
+ <what>Invalid write of size 1</what>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>bad_things</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+ <auxwhat>Address 0x........ is 0 bytes after a block of size 5 alloc'd</auxwhat>
+ <stack>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>malloc</fn>
+ <dir>...</dir>
+ <file>vg_replace_malloc.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>bad_things</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ <frame>
+ <ip>0x........</ip>
+ <obj>...</obj>
+ <fn>main</fn>
+ <dir>...</dir>
+ <file>threadname.c</file>
+ <line>...</line>
+ </frame>
+ </stack>
+</error>
+
+
+<status>
+ <state>FINISHED</state>
+ <time>...</time>
+</status>
+
+<errorcounts>
+ <pair>
+ <count>...</count>
+ <unique>0x........</unique>
+ </pair>
+ <pair>
+ <count>...</count>
+ <unique>0x........</unique>
+ </pair>
+ <pair>
+ <count>...</count>
+ <unique>0x........</unique>
+ </pair>
+ <pair>
+ <count>...</count>
+ <unique>0x........</unique>
+ </pair>
+ <pair>
+ <count>...</count>
+ <unique>0x........</unique>
+ </pair>
+</errorcounts>
+
+<suppcounts>...</suppcounts>
+
+</valgrindoutput>
+
Added: trunk/memcheck/tests/threadname_xml.vgtest
==============================================================================
--- trunk/memcheck/tests/threadname_xml.vgtest (added)
+++ trunk/memcheck/tests/threadname_xml.vgtest Mon Sep 16 17:08:50 2013
@@ -0,0 +1,3 @@
+prog: threadname
+vgopts: --xml=yes --xml-fd=2 --log-file=/dev/null
+stderr_filter: filter_xml
|
|
From: Petar J. <mip...@gm...> - 2013-09-17 01:32:05
|
Have you missed to add threadname_xml.stdout.exp and threadname.stdout.exp?
Regards,
Petar
On Mon, Sep 16, 2013 at 7:08 PM, <sv...@va...> wrote:
> Author: florian
> Date: Mon Sep 16 17:08:50 2013
> New Revision: 13553
>
> Log:
> Intercept prctl(PR_SET_NAME, name) and store the thread name so it
> can be used in error messages. That should be helpful when debugging
> multithreaded applications.
> Patch by Matthias Schwarzott <zz...@ge...> with some minor
> modifications. Fixes BZ 322254.
>
> Added:
> trunk/memcheck/tests/threadname.c
> trunk/memcheck/tests/threadname.stderr.exp
> trunk/memcheck/tests/threadname.vgtest
> trunk/memcheck/tests/threadname_xml.stderr.exp
> trunk/memcheck/tests/threadname_xml.vgtest
> Modified:
> trunk/NEWS
> trunk/coregrind/m_errormgr.c
> trunk/coregrind/m_gdbserver/server.c
> trunk/coregrind/m_scheduler/scheduler.c
> trunk/coregrind/m_syswrap/syswrap-linux.c
> trunk/coregrind/pub_core_threadstate.h
> trunk/docs/internals/xml-output-protocol4.txt
> trunk/memcheck/tests/ (props changed)
> trunk/memcheck/tests/Makefile.am
>
> Modified: trunk/NEWS
>
> ==============================================================================
> --- trunk/NEWS (original)
> +++ trunk/NEWS Mon Sep 16 17:08:50 2013
> @@ -464,6 +464,9 @@
> 321969 ppc32 and ppc64 don't support [lf]setxattr
> FIXED r13449
>
> +322254 Show threadname together with tid if set by application
> + FIXED r13553
> +
> 322368 Assertion failure in wqthread_hijack under OS X 10.8
> FIXED 13523
>
>
> Modified: trunk/coregrind/m_errormgr.c
>
> ==============================================================================
> --- trunk/coregrind/m_errormgr.c (original)
> +++ trunk/coregrind/m_errormgr.c Mon Sep 16 17:08:50 2013
> @@ -591,6 +591,10 @@
> VG_(printf_xml)("<error>\n");
> VG_(printf_xml)(" <unique>0x%x</unique>\n", err->unique);
> VG_(printf_xml)(" <tid>%d</tid>\n", err->tid);
> + ThreadState* tst = VG_(get_ThreadState)(err->tid);
> + if (tst->thread_name) {
> + VG_(printf_xml)(" <threadname>%s</threadname>\n",
> tst->thread_name);
> + }
>
> /* actually print it */
> VG_TDICT_CALL( tool_pp_Error, err );
> @@ -608,7 +612,12 @@
>
> 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) {
> + VG_(umsg)("Thread %d %s:\n", err->tid, tst->thread_name );
> + } else {
> + VG_(umsg)("Thread %d:\n", err->tid );
> + }
> last_tid_printed = err->tid;
> }
>
>
> Modified: trunk/coregrind/m_gdbserver/server.c
>
> ==============================================================================
> --- trunk/coregrind/m_gdbserver/server.c (original)
> +++ trunk/coregrind/m_gdbserver/server.c Mon Sep 16 17:08:50 2013
> @@ -588,10 +588,18 @@
> ti = gdb_id_to_thread (gdb_id);
> if (ti != NULL) {
> tst = (ThreadState *) inferior_target_data (ti);
> - /* Additional info is the tid and the thread status. */
> - VG_(snprintf) (status, sizeof(status), "tid %d %s",
> - tst->tid,
> - VG_(name_of_ThreadStatus)(tst->status));
> + /* Additional info is the tid, the thread status and the thread's
> + name, if any. */
> + if (tst->thread_name) {
> + 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 {
>
> Modified: trunk/coregrind/m_scheduler/scheduler.c
>
> ==============================================================================
> --- trunk/coregrind/m_scheduler/scheduler.c (original)
> +++ trunk/coregrind/m_scheduler/scheduler.c Mon Sep 16 17:08:50 2013
> @@ -238,6 +238,7 @@
> if (VG_(threads)[i].status == VgTs_Empty) {
> VG_(threads)[i].status = VgTs_Init;
> VG_(threads)[i].exitreason = VgSrc_None;
> + VG_(threads)[i].thread_name = NULL;
> return i;
> }
> }
> @@ -616,6 +617,7 @@
> VG_(threads)[i].client_stack_szB = 0;
> VG_(threads)[i].client_stack_highest_word = (Addr)NULL;
> VG_(threads)[i].err_disablement_level = 0;
> + VG_(threads)[i].thread_name = NULL;
> }
>
> tid_main = VG_(alloc_ThreadState)();
>
> Modified: trunk/coregrind/m_syswrap/syswrap-linux.c
>
> ==============================================================================
> --- trunk/coregrind/m_syswrap/syswrap-linux.c (original)
> +++ trunk/coregrind/m_syswrap/syswrap-linux.c Mon Sep 16 17:08:50 2013
> @@ -946,6 +946,18 @@
> case VKI_PR_GET_ENDIAN:
> POST_MEM_WRITE(ARG2, sizeof(Int));
> break;
> + case VKI_PR_SET_NAME:
> + {
> + const HChar* new_name = (const HChar*) ARG2;
> + if (new_name) { // Paranoia
> + ThreadState* tst = VG_(get_ThreadState)(tid);
> +
> + /* Don't bother reusing the memory. This is a rare event. */
> + tst->thread_name =
> + VG_(arena_strdup)(VG_AR_CORE, "syswrap.prctl", new_name);
> + }
> + }
> + break;
> }
> }
>
>
> Modified: trunk/coregrind/pub_core_threadstate.h
>
> ==============================================================================
> --- trunk/coregrind/pub_core_threadstate.h (original)
> +++ trunk/coregrind/pub_core_threadstate.h Mon Sep 16 17:08:50 2013
> @@ -357,6 +357,9 @@
> /* Per-thread jmp_buf to resume scheduler after a signal */
> Bool sched_jmpbuf_valid;
> VG_MINIMAL_JMP_BUF(sched_jmpbuf);
> +
> + /* This thread's name. NULL, if no name. */
> + HChar *thread_name;
> }
> ThreadState;
>
>
> Modified: trunk/docs/internals/xml-output-protocol4.txt
>
> ==============================================================================
> --- trunk/docs/internals/xml-output-protocol4.txt (original)
> +++ trunk/docs/internals/xml-output-protocol4.txt Mon Sep 16 17:08:50 2013
> @@ -408,6 +408,7 @@
> <error>
> <unique>HEX64</unique>
> <tid>INT</tid>
> + <threadname>NAME</threadname> if set
> <kind>KIND</kind>
>
> (either WHAT or XWHAT)
> @@ -428,6 +429,10 @@
> is arbitrary but may be used to determine which threads produced
> which errors (at least, the first instance of each error).
>
> +* The <threadname> tag identifies the name of the thread if it was
> + set by the client application. If no name was set, the tag is
> + omitted.
> +
> * The <kind> tag specifies one of a small number of fixed error types,
> so that GUIs may roughly categorise errors by type if they want.
> The tags themselves are tool-specific and are defined further
>
> Modified: trunk/memcheck/tests/Makefile.am
>
> ==============================================================================
> --- trunk/memcheck/tests/Makefile.am (original)
> +++ trunk/memcheck/tests/Makefile.am Mon Sep 16 17:08:50 2013
> @@ -260,7 +260,10 @@
> 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 threadname.stdout.exp threadname.stderr.exp \
> + threadname_xml.vgtest threadname_xml.stdout.exp \
> + threadname_xml.stderr.exp
>
> check_PROGRAMS = \
> accounting \
> @@ -335,7 +338,8 @@
> wcs \
> xml1 \
> wrap1 wrap2 wrap3 wrap4 wrap5 wrap6 wrap7 wrap7so.so wrap8 \
> - writev1
> + writev1 \
> + threadname
>
> if DWARF4
> check_PROGRAMS += dw4
> @@ -367,6 +371,7 @@
> err_disable3_LDADD = -lpthread
> err_disable4_LDADD = -lpthread
> thread_alloca_LDADD = -lpthread
> +threadname_LDADD = -lpthread
>
> error_counts_CFLAGS = $(AM_CFLAGS) @FLAG_W_NO_UNINITIALIZED@
>
>
> Added: trunk/memcheck/tests/threadname.c
>
> ==============================================================================
> --- trunk/memcheck/tests/threadname.c (added)
> +++ trunk/memcheck/tests/threadname.c Mon Sep 16 17:08:50 2013
> @@ -0,0 +1,80 @@
> +//#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>
> +
> +static pthread_t children[3];
> +
> +void bad_things(int offset)
> +{
> + char* m = malloc(sizeof(char)*offset);
> + m[offset] = 0;
> + free(m);
> +}
> +
> +void* child_fn_2 ( void* arg )
> +{
> + const char* threadname = "012345678901234";
> +
> + pthread_setname_np(pthread_self(), threadname);
> +
> + bad_things(4);
> +
> + return NULL;
> +}
> +
> +void* child_fn_1 ( void* arg )
> +{
> + const char* threadname = "try1";
> + int r;
> +
> + pthread_setname_np(pthread_self(), threadname);
> +
> + bad_things(3);
> +
> + r = pthread_create(&children[2], NULL, child_fn_2, NULL);
> + assert(!r);
> +
> + r = pthread_join(children[2], NULL);
> + assert(!r);
> +
> + return NULL;
> +}
> +
> +void* child_fn_0 ( void* arg )
> +{
> + int r;
> +
> + bad_things(2);
> +
> + r = pthread_create(&children[1], NULL, child_fn_1, NULL);
> + assert(!r);
> +
> + r = pthread_join(children[1], NULL);
> + assert(!r);
> +
> + return NULL;
> +}
> +
> +int main(int argc, const char** argv)
> +{
> + int r;
> +
> + bad_things(1);
> +
> + r = pthread_create(&children[0], NULL, child_fn_0, NULL);
> + assert(!r);
> +
> + r = pthread_join(children[0], NULL);
> + assert(!r);
> +
> + bad_things(5);
> +
> + return 0;
> +}
> +
>
> Added: trunk/memcheck/tests/threadname.stderr.exp
>
> ==============================================================================
> --- trunk/memcheck/tests/threadname.stderr.exp (added)
> +++ trunk/memcheck/tests/threadname.stderr.exp Mon Sep 16 17:08:50 2013
> @@ -0,0 +1,50 @@
> +Invalid write of size 1
> + at 0x........: bad_things (threadname.c:16)
> + by 0x........: main (threadname.c:68)
> + Address 0x........ is 0 bytes after a block of size 1 alloc'd
> + at 0x........: malloc (vg_replace_malloc.c:...)
> + by 0x........: bad_things (threadname.c:15)
> + by 0x........: main (threadname.c:68)
> +
> +Thread 2:
> +Invalid write of size 1
> + at 0x........: bad_things (threadname.c:16)
> + by 0x........: child_fn_0 (threadname.c:53)
> + ...
> + Address 0x........ is 0 bytes after a block of size 2 alloc'd
> + at 0x........: malloc (vg_replace_malloc.c:...)
> + by 0x........: bad_things (threadname.c:15)
> + by 0x........: child_fn_0 (threadname.c:53)
> + ...
> +
> +Thread 3 try1:
> +Invalid write of size 1
> + at 0x........: bad_things (threadname.c:16)
> + by 0x........: child_fn_1 (threadname.c:38)
> + ...
> + Address 0x........ is 0 bytes after a block of size 3 alloc'd
> + at 0x........: malloc (vg_replace_malloc.c:...)
> + by 0x........: bad_things (threadname.c:15)
> + by 0x........: child_fn_1 (threadname.c:38)
> + ...
> +
> +Thread 4 012345678901234:
> +Invalid write of size 1
> + at 0x........: bad_things (threadname.c:16)
> + by 0x........: child_fn_2 (threadname.c:26)
> + ...
> + Address 0x........ is 0 bytes after a block of size 4 alloc'd
> + at 0x........: malloc (vg_replace_malloc.c:...)
> + by 0x........: bad_things (threadname.c:15)
> + by 0x........: child_fn_2 (threadname.c:26)
> + ...
> +
> +Thread 1:
> +Invalid write of size 1
> + at 0x........: bad_things (threadname.c:16)
> + by 0x........: main (threadname.c:76)
> + Address 0x........ is 0 bytes after a block of size 5 alloc'd
> + at 0x........: malloc (vg_replace_malloc.c:...)
> + by 0x........: bad_things (threadname.c:15)
> + by 0x........: main (threadname.c:76)
> +
>
> Added: trunk/memcheck/tests/threadname.vgtest
>
> ==============================================================================
> --- trunk/memcheck/tests/threadname.vgtest (added)
> +++ trunk/memcheck/tests/threadname.vgtest Mon Sep 16 17:08:50 2013
> @@ -0,0 +1,2 @@
> +prog: threadname
> +vgopts: -q
>
> Added: trunk/memcheck/tests/threadname_xml.stderr.exp
>
> ==============================================================================
> --- trunk/memcheck/tests/threadname_xml.stderr.exp (added)
> +++ trunk/memcheck/tests/threadname_xml.stderr.exp Mon Sep 16 17:08:50 2013
> @@ -0,0 +1,373 @@
> +<?xml version="1.0"?>
> +
> +<valgrindoutput>
> +
> +<protocolversion>4</protocolversion>
> +<protocoltool>memcheck</protocoltool>
> +
> +<preamble>
> + <line>...</line>
> + <line>...</line>
> + <line>...</line>
> + <line>...</line>
> +</preamble>
> +
> +<pid>...</pid>
> +<ppid>...</ppid>
> +<tool>memcheck</tool>
> +
> +<args>
> + <vargv>...</vargv>
> + <argv>
> + <exe>./threadname</exe>
> + </argv>
> +</args>
> +
> +<status>
> + <state>RUNNING</state>
> + <time>...</time>
> +</status>
> +
> +<error>
> + <unique>0x........</unique>
> + <tid>...</tid>
> + <kind>InvalidWrite</kind>
> + <what>Invalid write of size 1</what>
> + <stack>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>bad_things</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>main</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + </stack>
> + <auxwhat>Address 0x........ is 0 bytes after a block of size 1
> alloc'd</auxwhat>
> + <stack>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>malloc</fn>
> + <dir>...</dir>
> + <file>vg_replace_malloc.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>bad_things</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>main</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + </stack>
> +</error>
> +
> +<error>
> + <unique>0x........</unique>
> + <tid>...</tid>
> + <kind>InvalidWrite</kind>
> + <what>Invalid write of size 1</what>
> + <stack>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>bad_things</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>child_fn_0</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>start_thread</fn>
> + <dir>...</dir>
> + <file>pthread_create.c</file>
> + <line>...</line>
> + </frame>
> + </stack>
> + <auxwhat>Address 0x........ is 0 bytes after a block of size 2
> alloc'd</auxwhat>
> + <stack>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>malloc</fn>
> + <dir>...</dir>
> + <file>vg_replace_malloc.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>bad_things</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>child_fn_0</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>start_thread</fn>
> + <dir>...</dir>
> + <file>pthread_create.c</file>
> + <line>...</line>
> + </frame>
> + </stack>
> +</error>
> +
> +<error>
> + <unique>0x........</unique>
> + <tid>...</tid>
> + <threadname>try1</threadname>
> + <kind>InvalidWrite</kind>
> + <what>Invalid write of size 1</what>
> + <stack>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>bad_things</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>child_fn_1</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>start_thread</fn>
> + <dir>...</dir>
> + <file>pthread_create.c</file>
> + <line>...</line>
> + </frame>
> + </stack>
> + <auxwhat>Address 0x........ is 0 bytes after a block of size 3
> alloc'd</auxwhat>
> + <stack>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>malloc</fn>
> + <dir>...</dir>
> + <file>vg_replace_malloc.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>bad_things</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>child_fn_1</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>start_thread</fn>
> + <dir>...</dir>
> + <file>pthread_create.c</file>
> + <line>...</line>
> + </frame>
> + </stack>
> +</error>
> +
> +<error>
> + <unique>0x........</unique>
> + <tid>...</tid>
> + <threadname>012345678901234</threadname>
> + <kind>InvalidWrite</kind>
> + <what>Invalid write of size 1</what>
> + <stack>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>bad_things</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>child_fn_2</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>start_thread</fn>
> + <dir>...</dir>
> + <file>pthread_create.c</file>
> + <line>...</line>
> + </frame>
> + </stack>
> + <auxwhat>Address 0x........ is 0 bytes after a block of size 4
> alloc'd</auxwhat>
> + <stack>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>malloc</fn>
> + <dir>...</dir>
> + <file>vg_replace_malloc.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>bad_things</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>child_fn_2</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>start_thread</fn>
> + <dir>...</dir>
> + <file>pthread_create.c</file>
> + <line>...</line>
> + </frame>
> + </stack>
> +</error>
> +
> +<error>
> + <unique>0x........</unique>
> + <tid>...</tid>
> + <kind>InvalidWrite</kind>
> + <what>Invalid write of size 1</what>
> + <stack>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>bad_things</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>main</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + </stack>
> + <auxwhat>Address 0x........ is 0 bytes after a block of size 5
> alloc'd</auxwhat>
> + <stack>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>malloc</fn>
> + <dir>...</dir>
> + <file>vg_replace_malloc.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>bad_things</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + <frame>
> + <ip>0x........</ip>
> + <obj>...</obj>
> + <fn>main</fn>
> + <dir>...</dir>
> + <file>threadname.c</file>
> + <line>...</line>
> + </frame>
> + </stack>
> +</error>
> +
> +
> +<status>
> + <state>FINISHED</state>
> + <time>...</time>
> +</status>
> +
> +<errorcounts>
> + <pair>
> + <count>...</count>
> + <unique>0x........</unique>
> + </pair>
> + <pair>
> + <count>...</count>
> + <unique>0x........</unique>
> + </pair>
> + <pair>
> + <count>...</count>
> + <unique>0x........</unique>
> + </pair>
> + <pair>
> + <count>...</count>
> + <unique>0x........</unique>
> + </pair>
> + <pair>
> + <count>...</count>
> + <unique>0x........</unique>
> + </pair>
> +</errorcounts>
> +
> +<suppcounts>...</suppcounts>
> +
> +</valgrindoutput>
> +
>
> Added: trunk/memcheck/tests/threadname_xml.vgtest
>
> ==============================================================================
> --- trunk/memcheck/tests/threadname_xml.vgtest (added)
> +++ trunk/memcheck/tests/threadname_xml.vgtest Mon Sep 16 17:08:50 2013
> @@ -0,0 +1,3 @@
> +prog: threadname
> +vgopts: --xml=yes --xml-fd=2 --log-file=/dev/null
> +stderr_filter: filter_xml
>
>
>
> ------------------------------------------------------------------------------
> LIMITED TIME SALE - Full Year of Microsoft Training For Just $49.99!
> 1,500+ hours of tutorials including VisualStudio 2012, Windows 8,
> SharePoint
> 2013, SQL 2012, MVC 4, more. BEST VALUE: New Multi-Library Power Pack
> includes
> Mobile, Cloud, Java, and UX Design. Lowest price ever! Ends 9/20/13.
> http://pubads.g.doubleclick.net/gampad/clk?id=58041151&iu=/4140/ostg.clktrk
> _______________________________________________
> Valgrind-developers mailing list
> Val...@li...
> https://lists.sourceforge.net/lists/listinfo/valgrind-developers
>
|
|
From: Florian K. <fl...@ei...> - 2013-09-17 07:48:48
|
On 09/17/2013 03:31 AM, Petar Jovanovic wrote: > Have you missed to add threadname_xml.stdout.exp and threadname.stdout.exp? > No. They are empty and vg_regtest allows to omit empty .exp files as a special case. <quote> # Expected stdout (filtered) is kept in <test>.stdout.exp* (can be more # than one expected output). It can be missing if it would be empty. </quote> Cheers, Florian |
|
From: Petar J. <mip...@gm...> - 2013-09-17 10:47:11
|
Why did you put them in EXTRA_DIST then? Regards, Petar On Tue, Sep 17, 2013 at 9:48 AM, Florian Krohm <fl...@ei...>wrote: > On 09/17/2013 03:31 AM, Petar Jovanovic wrote: > > Have you missed to add threadname_xml.stdout.exp and > threadname.stdout.exp? > > > > No. They are empty and vg_regtest allows to omit empty .exp files as a > special case. > > <quote> > # Expected stdout (filtered) is kept in <test>.stdout.exp* (can be more > # than one expected output). It can be missing if it would be empty. > </quote> > > Cheers, > Florian > > |
|
From: Florian K. <fl...@ei...> - 2013-09-17 14:57:38
|
On 09/17/2013 12:47 PM, Petar Jovanovic wrote:
> Why did you put them in EXTRA_DIST then?
Good point. I did not notice and will fix that (as well as the other
issues related to that patch that surfaced during last night's build).
Florian
|
|
From: Philippe W. <phi...@sk...> - 2013-09-17 15:10:46
|
Hello,
I have a question about the relationship/overlap of this change
with the drd.h functionality ANNOTATE_THREAD_NAME
(also present in helgrind.h but left unimplemented).
Shouldn't this macro be implemented in the core valgrind.h ?
(so that all tools can benefit from that) ?
Not very clear to me what happens now in drd if
there is a call to both PR_SET_NAME and to ANNOTATE_THREAD_NAME.
Also a small comment:
On Mon, 2013-09-16 at 17:08 +0000, sv...@va... wrote:
> + case VKI_PR_SET_NAME:
> + {
> + const HChar* new_name = (const HChar*) ARG2;
> + if (new_name) { // Paranoia
> + ThreadState* tst = VG_(get_ThreadState)(tid);
> +
> + /* Don't bother reusing the memory. This is a rare event. */
> + tst->thread_name =
> + VG_(arena_strdup)(VG_AR_CORE, "syswrap.prctl", new_name);
If there are more than one call to PR_SET_NAME, this is causing a leak.
So, it looks cleaner to me to free the old (non NULL) value
Also, it is not clear to me what happens when a tid entry is re-used.
The thread name of a previous thread can then be wrongly re-used for
the new thread, either before a new call to PR_SET_NAME,
or if the new thread does not call PR_SET_NAME, then the old name
will be re-used for the "wrong" thread.
Philippe
|
|
From: Bart V. A. <bva...@ac...> - 2013-09-17 17:57:54
|
On 09/17/13 17:10, Philippe Waroquiers wrote:
> Hello,
> I have a question about the relationship/overlap of this change
> with the drd.h functionality ANNOTATE_THREAD_NAME
> (also present in helgrind.h but left unimplemented).
>
> Shouldn't this macro be implemented in the core valgrind.h ?
> (so that all tools can benefit from that) ?
> Not very clear to me what happens now in drd if
> there is a call to both PR_SET_NAME and to ANNOTATE_THREAD_NAME.
>
>
> Also a small comment:
>
> On Mon, 2013-09-16 at 17:08 +0000, sv...@va... wrote:
>> + case VKI_PR_SET_NAME:
>> + {
>> + const HChar* new_name = (const HChar*) ARG2;
>> + if (new_name) { // Paranoia
>> + ThreadState* tst = VG_(get_ThreadState)(tid);
>> +
>> + /* Don't bother reusing the memory. This is a rare event. */
>> + tst->thread_name =
>> + VG_(arena_strdup)(VG_AR_CORE, "syswrap.prctl", new_name);
> If there are more than one call to PR_SET_NAME, this is causing a leak.
> So, it looks cleaner to me to free the old (non NULL) value
>
> Also, it is not clear to me what happens when a tid entry is re-used.
> The thread name of a previous thread can then be wrongly re-used for
> the new thread, either before a new call to PR_SET_NAME,
> or if the new thread does not call PR_SET_NAME, then the old name
> will be re-used for the "wrong" thread.
You have a point here. I think the thread name should be freed when a
thread stops.
Bart.
|
|
From: Petar J. <mip...@gm...> - 2013-09-17 15:26:46
|
On Tue, Sep 17, 2013 at 4:57 PM, Florian Krohm <fl...@ei...>wrote:
> On 09/17/2013 12:47 PM, Petar Jovanovic wrote:
> > Why did you put them in EXTRA_DIST then?
>
> Good point. I did not notice and will fix that (as well as the other
> issues related to that patch that surfaced during last night's build).
>
> Florian
>
>
>
There is also a problem with the use of pthread_setname_np. That was not
available prior to glibc 2.12 and the test will fail to compile on any
platform with glibc older than that. One option would be to protect the
whole test program with a build flag, e.g.
#ifndef HAVE_PTHREAD_SETNAME_NP
#ifdef __GLIBC_PREREQ
#if __GLIBC_PREREQ(2,12)
#define HAVE_PTHREAD_SETNAME_NP
#endif
#endif
#endif // ifndef HAVE_PTHREAD_SETNAME_NP
#ifndef HAVE_PTHREAD_SETNAME_NP
int main() { return 0; }
#else
// The test
#endif
Regards,
Petar
|
|
From: Florian K. <fl...@ei...> - 2013-09-17 20:31:24
|
On 09/17/2013 05:26 PM, Petar Jovanovic wrote:
>>
> There is also a problem with the use of pthread_setname_np. That was not
> available prior to glibc 2.12 and the test will fail to compile on any
> platform with glibc older than that. One option would be to protect the
> whole test program with a build flag, e.g.
If we do it this way we need 2 stderr.exp files. I've chosen a slightly
different way to accomplish this so there is only a single .stderr.exp
file. Should be fixed now in r13557.
Florian
>
> #ifndef HAVE_PTHREAD_SETNAME_NP
>
> #ifdef __GLIBC_PREREQ
> #if __GLIBC_PREREQ(2,12)
> #define HAVE_PTHREAD_SETNAME_NP
> #endif
> #endif
>
> #endif // ifndef HAVE_PTHREAD_SETNAME_NP
>
> #ifndef HAVE_PTHREAD_SETNAME_NP
> int main() { return 0; }
> #else
>
> // The test
> #endif
>
>
> Regards,
> Petar
>
|
|
From: Florian K. <fl...@ei...> - 2013-09-17 22:25:02
|
On 09/17/2013 05:10 PM, Philippe Waroquiers wrote:
> Hello,
> I have a question about the relationship/overlap of this change
> with the drd.h functionality ANNOTATE_THREAD_NAME
> (also present in helgrind.h but left unimplemented).
>
> Shouldn't this macro be implemented in the core valgrind.h ?
> (so that all tools can benefit from that) ?
Ideally, yes, for the benefit of people running on old enough glibc
versions. And, ideally again, all tools should support that annotation.
But I don't see that happen. And I haven't seen any demand for it.
That said, I'd leave things as they are.
> Not very clear to me what happens now in drd if
> there is a call to both PR_SET_NAME and to ANNOTATE_THREAD_NAME.
drd sets tool_show_ThreadIDs_for_errors to False, so m_errormgr won't
output thread IDs and names. No problems here.
>
> Also a small comment:
>
> On Mon, 2013-09-16 at 17:08 +0000, sv...@va... wrote:
>> + case VKI_PR_SET_NAME:
>> + {
>> + const HChar* new_name = (const HChar*) ARG2;
>> + if (new_name) { // Paranoia
>> + ThreadState* tst = VG_(get_ThreadState)(tid);
>> +
>> + /* Don't bother reusing the memory. This is a rare event. */
>> + tst->thread_name =
>> + VG_(arena_strdup)(VG_AR_CORE, "syswrap.prctl", new_name);
> If there are more than one call to PR_SET_NAME, this is causing a leak.
> So, it looks cleaner to me to free the old (non NULL) value
Yes, it is cleaner. I'll change that (tomorrow).
> Also, it is not clear to me what happens when a tid entry is re-used.
How is a tid reused? Does that happen by calling VG_(alloc_ThreadState)
which then recycles an old tid? In that case we're good because the
thread name is set to NULL (but probably should free the thread name, if
there is one).
If there are other ways to re-use a tid can you give me some pointers?
I know you're very familiar with that code, so saves me some time :)
Florian
|
|
From: Philippe W. <phi...@sk...> - 2013-09-17 23:03:51
|
On Wed, 2013-09-18 at 00:24 +0200, Florian Krohm wrote: > On 09/17/2013 05:10 PM, Philippe Waroquiers wrote: > > Hello, > > I have a question about the relationship/overlap of this change > > with the drd.h functionality ANNOTATE_THREAD_NAME > > (also present in helgrind.h but left unimplemented). > > > > Shouldn't this macro be implemented in the core valgrind.h ? > > (so that all tools can benefit from that) ? > > Ideally, yes, for the benefit of people running on old enough glibc > versions. And, ideally again, all tools should support that annotation. > But I don't see that happen. And I haven't seen any demand for it. > That said, I'd leave things as they are. Fair enough. If a generalisation becomes desirable, it is easy to implement in the future (and redirect the drd request to the core request). > > > Not very clear to me what happens now in drd if > > there is a call to both PR_SET_NAME and to ANNOTATE_THREAD_NAME. > > drd sets tool_show_ThreadIDs_for_errors to False, so m_errormgr won't > output thread IDs and names. No problems here. Ok. > How is a tid reused? Does that happen by calling VG_(alloc_ThreadState) > which then recycles an old tid? In that case we're good because the > thread name is set to NULL (but probably should free the thread name, if > there is one). > If there are other ways to re-use a tid can you give me some pointers? > I know you're very familiar with that code, so saves me some time :) Humph, not so sure of my level of familiarity. I think the only way to get (and so reuse) a tid is by calling VG_(alloc_ThreadState). So, should be ok by free-ing the thread name in VG_(alloc_ThreadState) (and in PR_SET_NAME). Philippe |