tsan: better report formatting for Go
authorDmitry Vyukov <dvyukov@google.com>
Fri, 16 Aug 2013 11:15:14 +0000 (11:15 +0000)
committerDmitry Vyukov <dvyukov@google.com>
Fri, 16 Aug 2013 11:15:14 +0000 (11:15 +0000)
Say that gorotuine 1 is main goroutine.
Remove excessive new line.

llvm-svn: 188542

compiler-rt/lib/tsan/go/buildgo.sh
compiler-rt/lib/tsan/go/test.c
compiler-rt/lib/tsan/rtl/tsan_report.cc

index bffa276..52a056a 100755 (executable)
@@ -26,7 +26,7 @@ SRCS="
 
 if [ "`uname -a | grep Linux`" != "" ]; then
        SUFFIX="linux_amd64"
-       OSCFLAGS="-fPIC -ffreestanding"
+       OSCFLAGS="-fPIC -ffreestanding -Wno-maybe-uninitialized"
        OSLDFLAGS="-lpthread -fPIC -fpie"
        SRCS+="
                ../rtl/tsan_platform_linux.cc
@@ -65,7 +65,7 @@ for F in $SRCS; do
        cat $F >> gotsan.cc
 done
 
-FLAGS=" -I../rtl -I../.. -I../../sanitizer_common -I../../../include -m64 -Wall -Werror -Wno-maybe-uninitialized -fno-exceptions -fno-rtti -DTSAN_GO -DSANITIZER_GO -DTSAN_SHADOW_COUNT=4 $OSCFLAGS"
+FLAGS=" -I../rtl -I../.. -I../../sanitizer_common -I../../../include -m64 -Wall -Werror -fno-exceptions -fno-rtti -DTSAN_GO -DSANITIZER_GO -DTSAN_SHADOW_COUNT=4 $OSCFLAGS"
 if [ "$DEBUG" == "" ]; then
        FLAGS+=" -DTSAN_DEBUG=0 -O3 -fomit-frame-pointer"
 else
index 902dfc9..859b35d 100644 (file)
@@ -34,20 +34,32 @@ int __tsan_symbolize(void *pc, char **img, char **rtn, char **file, int *l) {
 
 char buf[10];
 
+void foobar() {}
+void barfoo() {}
+
 int main(void) {
   void *thr0 = 0;
   __tsan_init(&thr0);
   __tsan_map_shadow(buf, sizeof(buf) + 4096);
-  __tsan_func_enter(thr0, &main);
+  __tsan_func_enter(thr0, (char*)&main + 1);
   __tsan_malloc(thr0, buf, 10, 0);
   __tsan_release(thr0, buf);
   __tsan_release_merge(thr0, buf);
   void *thr1 = 0;
-  __tsan_go_start(thr0, &thr1, 0);
-  __tsan_write(thr1, buf, 0);
+  __tsan_go_start(thr0, &thr1, (char*)&barfoo + 1);
+  void *thr2 = 0;
+  __tsan_go_start(thr0, &thr2, (char*)&barfoo + 1);
+  __tsan_func_enter(thr1, (char*)&foobar + 1);
+  __tsan_func_enter(thr1, (char*)&foobar + 1);
+  __tsan_write(thr1, buf, (char*)&barfoo + 1);
   __tsan_acquire(thr1, buf);
+  __tsan_func_exit(thr1);
+  __tsan_func_exit(thr1);
   __tsan_go_end(thr1);
-  __tsan_read(thr0, buf, 0);
+  __tsan_func_enter(thr2, (char*)&foobar + 1);
+  __tsan_read(thr2, buf, (char*)&barfoo + 1);
+  __tsan_func_exit(thr2);
+  __tsan_go_end(thr2);
   __tsan_free(buf);
   __tsan_func_exit(thr0);
   __tsan_fini();
index c95c5c8..2bcf419 100644 (file)
@@ -212,31 +212,37 @@ void PrintReport(const ReportDesc *rep) {
   Printf("==================\n");
 }
 
-#else
+#else  // #ifndef TSAN_GO
+
+const int kMainThreadId = 1;
 
 void PrintStack(const ReportStack *ent) {
   if (ent == 0) {
-    Printf("  [failed to restore the stack]\n\n");
+    Printf("  [failed to restore the stack]\n");
     return;
   }
   for (int i = 0; ent; ent = ent->next, i++) {
     Printf("  %s()\n      %s:%d +0x%zx\n",
         ent->func, ent->file, ent->line, (void*)ent->offset);
   }
-  Printf("\n");
 }
 
 static void PrintMop(const ReportMop *mop, bool first) {
-  Printf("%s by goroutine %d:\n",
+  Printf("\n");
+  Printf("%s by ",
       (first ? (mop->write ? "Write" : "Read")
-             : (mop->write ? "Previous write" : "Previous read")),
-      mop->tid);
+             : (mop->write ? "Previous write" : "Previous read")));
+  if (mop->tid == kMainThreadId)
+    Printf("main goroutine:\n");
+  else
+    Printf("goroutine %d:\n", mop->tid);
   PrintStack(mop->stack);
 }
 
 static void PrintThread(const ReportThread *rt) {
-  if (rt->id == 0)  // Little sense in describing the main thread.
+  if (rt->id == kMainThreadId)
     return;
+  Printf("\n");
   Printf("Goroutine %d (%s) created at:\n",
     rt->id, rt->running ? "running" : "finished");
   PrintStack(rt->stack);
@@ -244,7 +250,7 @@ static void PrintThread(const ReportThread *rt) {
 
 void PrintReport(const ReportDesc *rep) {
   Printf("==================\n");
-  Printf("WARNING: DATA RACE\n");
+  Printf("WARNING: DATA RACE");
   for (uptr i = 0; i < rep->mops.Size(); i++)
     PrintMop(rep->mops[i], i == 0);
   for (uptr i = 0; i < rep->threads.Size(); i++)