2020namespace __asan {
2121
2222AsanThreadIdAndName::AsanThreadIdAndName (AsanThreadContext *t) {
23- Init (t->tid , t->name );
24- }
25-
26- AsanThreadIdAndName::AsanThreadIdAndName (u32 tid) {
27- if (tid == kInvalidTid ) {
28- Init (tid, " " );
29- } else {
30- asanThreadRegistry ().CheckLocked ();
31- AsanThreadContext *t = GetThreadContextByTidLocked (tid);
32- Init (tid, t->name );
23+ if (!t) {
24+ internal_snprintf (name, sizeof (name), " T-1" );
25+ return ;
3326 }
27+ int len = internal_snprintf (name, sizeof (name), " T%llu" , t->unique_id );
28+ CHECK (((unsigned int )len) < sizeof (name));
29+ if (internal_strlen (t->name ))
30+ internal_snprintf (&name[len], sizeof (name) - len, " (%s)" , t->name );
3431}
3532
36- void AsanThreadIdAndName::Init (u32 tid, const char *tname) {
37- int len = internal_snprintf (name, sizeof (name), " T%d" , tid);
38- CHECK (((unsigned int )len) < sizeof (name));
39- if (tname[0 ] != ' \0 ' )
40- internal_snprintf (&name[len], sizeof (name) - len, " (%s)" , tname);
33+ AsanThreadIdAndName::AsanThreadIdAndName (u32 tid)
34+ : AsanThreadIdAndName(
35+ tid == kInvalidTid ? nullptr : GetThreadContextByTidLocked(tid)) {
36+ asanThreadRegistry ().CheckLocked ();
4137}
4238
4339void DescribeThread (AsanThreadContext *context) {
@@ -48,9 +44,20 @@ void DescribeThread(AsanThreadContext *context) {
4844 return ;
4945 }
5046 context->announced = true ;
47+
48+ AsanThreadContext *parent_context =
49+ context->parent_tid == kInvalidTid
50+ ? nullptr
51+ : GetThreadContextByTidLocked (context->parent_tid );
52+
53+ // `context->parent_tid` may point to reused slot. Check `unique_id` which
54+ // is always smaller for the parent, always greater for a new user.
55+ if (context->unique_id <= parent_context->unique_id )
56+ parent_context = nullptr ;
57+
5158 InternalScopedString str;
5259 str.AppendF (" Thread %s" , AsanThreadIdAndName (context).c_str ());
53- if (context-> parent_tid == kInvalidTid ) {
60+ if (!parent_context ) {
5461 str.Append (" created by unknown thread\n " );
5562 Printf (" %s" , str.data ());
5663 return ;
@@ -60,11 +67,8 @@ void DescribeThread(AsanThreadContext *context) {
6067 Printf (" %s" , str.data ());
6168 StackDepotGet (context->stack_id ).Print ();
6269 // Recursively described parent thread if needed.
63- if (flags ()->print_full_thread_history ) {
64- AsanThreadContext *parent_context =
65- GetThreadContextByTidLocked (context->parent_tid );
70+ if (flags ()->print_full_thread_history )
6671 DescribeThread (parent_context);
67- }
6872}
6973
7074// Shadow descriptions
@@ -245,11 +249,11 @@ static void PrintAccessAndVarIntersection(const StackVarDescr &var, uptr addr,
245249 InternalScopedString str;
246250 str.AppendF (" [%zd, %zd)" , var.beg , var_end);
247251 // Render variable name.
248- str.AppendF (" '" );
252+ str.Append (" '" );
249253 for (uptr i = 0 ; i < var.name_len ; ++i) {
250254 str.AppendF (" %c" , var.name_pos [i]);
251255 }
252- str.AppendF (" '" );
256+ str.Append (" '" );
253257 if (var.line > 0 ) {
254258 str.AppendF (" (line %zd)" , var.line );
255259 }
@@ -260,7 +264,7 @@ static void PrintAccessAndVarIntersection(const StackVarDescr &var, uptr addr,
260264 str.AppendF (" %s <== Memory access at offset %zd %s this variable%s\n " ,
261265 d.Location (), addr, pos_descr, d.Default ());
262266 } else {
263- str.AppendF (" \n " );
267+ str.Append (" \n " );
264268 }
265269 Printf (" %s" , str.data ());
266270}
@@ -292,7 +296,7 @@ static void DescribeAddressRelativeToGlobal(uptr addr, uptr access_size,
292296 str.AppendF (" global variable '%s' defined in '" ,
293297 MaybeDemangleGlobalName (g.name ));
294298 PrintGlobalLocation (&str, g, /* print_module_name=*/ false );
295- str.AppendF (" ' (0x%zx ) of size %zu\n " , g.beg , g.size );
299+ str.AppendF (" ' (%p ) of size %zu\n " , ( void *) g.beg , g.size );
296300 str.Append (d.Default ());
297301 PrintGlobalNameIfASCII (&str, g);
298302 Printf (" %s" , str.data ());
0 commit comments