Commit 8e351ae3 authored by Hana Kim's avatar Hana Kim Committed by Hyang-Ah Hana Kim

cmd/trace: include taskless spans in /usertasks.

Change-Id: Id4e3407ba497a018d5ace92813ba8e9653d0ac7d
Reviewed-on: https://go-review.googlesource.com/104976Reviewed-by: default avatarHeschi Kreinick <heschi@google.com>
Run-TryBot: Heschi Kreinick <heschi@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
parent fc8967e3
...@@ -306,13 +306,15 @@ func analyzeAnnotations() (annotationAnalysisResult, error) { ...@@ -306,13 +306,15 @@ func analyzeAnnotations() (annotationAnalysisResult, error) {
// combine span info. // combine span info.
analyzeGoroutines(events) analyzeGoroutines(events)
for goid, stats := range gs { for goid, stats := range gs {
// gs is a global var defined in goroutines.go as a result
// of analyzeGoroutines. TODO(hyangah): fix this not to depend
// on a 'global' var.
for _, s := range stats.Spans { for _, s := range stats.Spans {
if s.TaskID == 0 { if s.TaskID != 0 {
continue
}
task := tasks.task(s.TaskID) task := tasks.task(s.TaskID)
task.goroutines[goid] = struct{}{} task.goroutines[goid] = struct{}{}
task.spans = append(task.spans, spanDesc{UserSpanDesc: s, G: goid}) task.spans = append(task.spans, spanDesc{UserSpanDesc: s, G: goid})
}
var frame trace.Frame var frame trace.Frame
if s.Start != nil { if s.Start != nil {
frame = *s.Start.Stk[0] frame = *s.Start.Stk[0]
...@@ -322,7 +324,7 @@ func analyzeAnnotations() (annotationAnalysisResult, error) { ...@@ -322,7 +324,7 @@ func analyzeAnnotations() (annotationAnalysisResult, error) {
} }
} }
// sort spans based on the timestamps. // sort spans in tasks based on the timestamps.
for _, task := range tasks { for _, task := range tasks {
sort.SliceStable(task.spans, func(i, j int) bool { sort.SliceStable(task.spans, func(i, j int) bool {
si, sj := task.spans[i].firstTimestamp(), task.spans[j].firstTimestamp() si, sj := task.spans[i].firstTimestamp(), task.spans[j].firstTimestamp()
...@@ -408,7 +410,6 @@ func (tasks allTasks) task(taskID uint64) *taskDesc { ...@@ -408,7 +410,6 @@ func (tasks allTasks) task(taskID uint64) *taskDesc {
func (task *taskDesc) addEvent(ev *trace.Event) { func (task *taskDesc) addEvent(ev *trace.Event) {
if task == nil { if task == nil {
// TODO(hyangah): handle spans with no task.
return return
} }
...@@ -1229,7 +1230,7 @@ function reloadTable(key, value) { ...@@ -1229,7 +1230,7 @@ function reloadTable(key, value) {
{{range .Data}} {{range .Data}}
<tr> <tr>
<td> <a href="/trace?goid={{.G}}">{{.G}}</a> </td> <td> <a href="/trace?goid={{.G}}">{{.G}}</a> </td>
<td> <a href="/trace?taskid={{.TaskID}}">{{.TaskID}}</a> </td> <td> {{if .TaskID}}<a href="/trace?taskid={{.TaskID}}">{{.TaskID}}</a>{{end}} </td>
<td> {{prettyDuration .TotalTime}} </td> <td> {{prettyDuration .TotalTime}} </td>
<td> <td>
<div class="stacked-bar-graph"> <div class="stacked-bar-graph">
......
...@@ -10,6 +10,7 @@ import ( ...@@ -10,6 +10,7 @@ import (
"reflect" "reflect"
"runtime/debug" "runtime/debug"
"runtime/trace" "runtime/trace"
"sort"
"sync" "sync"
"testing" "testing"
"time" "time"
...@@ -98,7 +99,6 @@ func TestAnalyzeAnnotations(t *testing.T) { ...@@ -98,7 +99,6 @@ func TestAnalyzeAnnotations(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("failed to analyzeAnnotations: %v", err) t.Fatalf("failed to analyzeAnnotations: %v", err)
} }
tasks := res.tasks
// For prog0, we expect // For prog0, we expect
// - task with name = "task0", with three spans. // - task with name = "task0", with three spans.
...@@ -119,14 +119,14 @@ func TestAnalyzeAnnotations(t *testing.T) { ...@@ -119,14 +119,14 @@ func TestAnalyzeAnnotations(t *testing.T) {
}, },
} }
for _, task := range tasks { for _, task := range res.tasks {
want, ok := wantTasks[task.name] want, ok := wantTasks[task.name]
if !ok { if !ok {
t.Errorf("unexpected task: %s", task) t.Errorf("unexpected task: %s", task)
continue continue
} }
if task.complete() != want.complete || len(task.goroutines) != want.goroutines || !reflect.DeepEqual(spanNames(task), want.spans) { if task.complete() != want.complete || len(task.goroutines) != want.goroutines || !reflect.DeepEqual(spanNames(task), want.spans) {
t.Errorf("got %v; want %+v", task, want) t.Errorf("got task %v; want %+v", task, want)
} }
delete(wantTasks, task.name) delete(wantTasks, task.name)
...@@ -134,6 +134,24 @@ func TestAnalyzeAnnotations(t *testing.T) { ...@@ -134,6 +134,24 @@ func TestAnalyzeAnnotations(t *testing.T) {
if len(wantTasks) > 0 { if len(wantTasks) > 0 {
t.Errorf("no more tasks; want %+v", wantTasks) t.Errorf("no more tasks; want %+v", wantTasks)
} }
wantSpans := []string{
"", // an auto-created span for the goroutine 3
"taskless.span",
"task0.span0",
"task0.span1",
"task0.span2",
}
var gotSpans []string
for spanID := range res.spans {
gotSpans = append(gotSpans, spanID.Type)
}
sort.Strings(wantSpans)
sort.Strings(gotSpans)
if !reflect.DeepEqual(gotSpans, wantSpans) {
t.Errorf("got spans %q, want spans %q", gotSpans, wantSpans)
}
} }
// prog1 creates a task hierarchy consisting of three tasks. // prog1 creates a task hierarchy consisting of three tasks.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment