@@ -13,7 +13,6 @@ import (
1313 "fmt"
1414 "net/url"
1515 "os"
16- "path/filepath"
1716 "sort"
1817 "strings"
1918 "unicode"
@@ -236,63 +235,37 @@ func (a *Args) merge(r *Args) Args {
236235
237236// Call is an item in the stack trace.
238237type Call struct {
239- // SrcPath is the full path name of the source file as seen in the trace.
240- SrcPath string
241- // LocalSrcPath is the full path name of the source file as seen in the host,
242- // if found.
243- LocalSrcPath string
244- // Line is the line number.
245- Line int
238+ // The following are initialized on the first line of the call stack.
246239 // Func is the fully qualified function name (encoded).
247240 Func Func
248241 // Args is the call arguments.
249242 Args Args
250243
244+ // The following are initialized on the second line of the call stack.
245+ // SrcPath is the full path name of the source file as seen in the trace.
246+ SrcPath string
247+ // Line is the line number.
248+ Line int
249+ // SrcName returns the base file name of the source file. It is a subset of
250+ // SrcPath.
251+ SrcName string
252+ // DirSrc is one directory plus the file name of the source file. It is a
253+ // subset of SrcPath.
254+ DirSrc string
255+
251256 // The following are only set if guesspaths is set to true in ParseDump().
252- // IsStdlib is true if it is a Go standard library function. This includes
253- // the 'go test' generated main executable .
254- IsStdlib bool
257+ // LocalSrcPath is the full path name of the source file as seen in the host,
258+ // if found .
259+ LocalSrcPath string
255260 // RelSrcPath is the relative path to GOROOT or GOPATH. Only set when
256261 // Augment() is called.
257262 RelSrcPath string
258- }
259-
260- // equal returns true only if both calls are exactly equal.
261- func (c * Call ) equal (r * Call ) bool {
262- return c .Line == r .Line && c .Func .Complete == r .Func .Complete && c .SrcPath == r .SrcPath && c .Args .equal (& r .Args )
263- }
264-
265- // similar returns true if the two Call are equal or almost but not quite
266- // equal.
267- func (c * Call ) similar (r * Call , similar Similarity ) bool {
268- return c .Line == r .Line && c .Func .Complete == r .Func .Complete && c .SrcPath == r .SrcPath && c .Args .similar (& r .Args , similar )
269- }
270-
271- // merge merges two similar Call, zapping out differences.
272- func (c * Call ) merge (r * Call ) Call {
273- return Call {
274- SrcPath : c .SrcPath ,
275- LocalSrcPath : c .LocalSrcPath ,
276- Line : c .Line ,
277- Func : c .Func ,
278- Args : c .Args .merge (& r .Args ),
279- IsStdlib : c .IsStdlib ,
280- RelSrcPath : c .RelSrcPath ,
281- }
282- }
283-
284- // SrcName returns the base file name of the source file.
285- func (c * Call ) SrcName () string {
286- return filepath .Base (c .SrcPath )
287- }
263+ // IsStdlib is true if it is a Go standard library function. This includes
264+ // the 'go test' generated main executable.
265+ IsStdlib bool
288266
289- // PkgSrc returns one directory plus the file name of the source file.
290- //
291- // Since the package name can differ from the package import path, the result
292- // is incorrect when there's a mismatch between the directory name containing
293- // the package and the package name.
294- func (c * Call ) PkgSrc () string {
295- return pathJoin (filepath .Base (filepath .Dir (c .SrcPath )), c .SrcName ())
267+ // Disallow initialization with unnamed parameters.
268+ _ struct {}
296269}
297270
298271// ImportPath returns the fully qualified package import path.
@@ -315,6 +288,20 @@ func (c *Call) ImportPath() string {
315288 return ""
316289}
317290
291+ // Init initializes SrcPath, SrcName, DirName, Line and IsStdlib for test main.
292+ func (c * Call ) init (srcPath string , line int ) {
293+ c .SrcPath = srcPath
294+ c .Line = line
295+ if i := strings .LastIndexByte (c .SrcPath , '/' ); i != - 1 {
296+ c .SrcName = c .SrcPath [i + 1 :]
297+ if i = strings .LastIndexByte (c .SrcPath [:i ], '/' ); i != - 1 {
298+ c .DirSrc = c .SrcPath [i + 1 :]
299+ }
300+ }
301+ // Consider _test/_testmain.go as stdlib since it's injected by "go test".
302+ c .IsStdlib = c .DirSrc == testMainSrc
303+ }
304+
318305const testMainSrc = "_test" + string (os .PathSeparator ) + "_testmain.go"
319306
320307// updateLocations initializes LocalSrcPath, RelSrcPath and IsStdlib.
@@ -332,7 +319,7 @@ func (c *Call) updateLocations(goroot, localgoroot, localgomod, gomodImportPath
332319 c .RelSrcPath = c .SrcPath [len (prefix ):]
333320 c .LocalSrcPath = pathJoin (localgoroot , "src" , c .RelSrcPath )
334321 c .IsStdlib = true
335- goto done
322+ return
336323 }
337324 }
338325 // Check GOPATH.
@@ -341,13 +328,13 @@ func (c *Call) updateLocations(goroot, localgoroot, localgomod, gomodImportPath
341328 if p := prefix + "/src/" ; strings .HasPrefix (c .SrcPath , p ) {
342329 c .RelSrcPath = c .SrcPath [len (p ):]
343330 c .LocalSrcPath = pathJoin (dest , "src" , c .RelSrcPath )
344- goto done
331+ return
345332 }
346333 // For modules, the path has to be altered, as it contains the version.
347334 if p := prefix + "/pkg/mod/" ; strings .HasPrefix (c .SrcPath , p ) {
348335 c .RelSrcPath = c .SrcPath [len (p ):]
349336 c .LocalSrcPath = pathJoin (dest , "pkg/mod" , c .RelSrcPath )
350- goto done
337+ return
351338 }
352339 }
353340 // Go module path detection only works with stack traces created on the local
@@ -356,13 +343,34 @@ func (c *Call) updateLocations(goroot, localgoroot, localgomod, gomodImportPath
356343 if prefix := localgomod + "/" ; strings .HasPrefix (c .SrcPath , prefix ) {
357344 c .RelSrcPath = gomodImportPath + "/" + c .SrcPath [len (prefix ):]
358345 c .LocalSrcPath = c .SrcPath
359- goto done
346+ return
360347 }
361348 }
362- done:
363- if ! c .IsStdlib {
364- // Consider _test/_testmain.go as stdlib since it's injected by "go test".
365- c .IsStdlib = c .PkgSrc () == testMainSrc
349+ }
350+
351+ // equal returns true only if both calls are exactly equal.
352+ func (c * Call ) equal (r * Call ) bool {
353+ return c .Line == r .Line && c .Func .Complete == r .Func .Complete && c .SrcPath == r .SrcPath && c .Args .equal (& r .Args )
354+ }
355+
356+ // similar returns true if the two Call are equal or almost but not quite
357+ // equal.
358+ func (c * Call ) similar (r * Call , similar Similarity ) bool {
359+ return c .Line == r .Line && c .Func .Complete == r .Func .Complete && c .SrcPath == r .SrcPath && c .Args .similar (& r .Args , similar )
360+ }
361+
362+ // merge merges two similar Call, zapping out differences.
363+ func (c * Call ) merge (r * Call ) Call {
364+ return Call {
365+ Func : c .Func ,
366+ Args : c .Args .merge (& r .Args ),
367+ SrcPath : c .SrcPath ,
368+ Line : c .Line ,
369+ SrcName : c .SrcName ,
370+ DirSrc : c .DirSrc ,
371+ LocalSrcPath : c .LocalSrcPath ,
372+ RelSrcPath : c .RelSrcPath ,
373+ IsStdlib : c .IsStdlib ,
366374 }
367375}
368376
@@ -374,6 +382,9 @@ type Stack struct {
374382 // Elided is set when there's >100 items in Stack, currently hardcoded in
375383 // package runtime.
376384 Elided bool
385+
386+ // Disallow initialization with unnamed parameters.
387+ _ struct {}
377388}
378389
379390// equal returns true on if both call stacks are exactly equal.
@@ -462,16 +473,17 @@ func (s *Stack) less(r *Stack) bool {
462473 if s .Calls [x ].Func .Complete > r .Calls [x ].Func .Complete {
463474 return true
464475 }
465- if s .Calls [x ].PkgSrc () < r .Calls [x ].PkgSrc () {
476+ if s .Calls [x ].DirSrc < r .Calls [x ].DirSrc {
466477 return true
467478 }
468- if s .Calls [x ].PkgSrc () > r .Calls [x ].PkgSrc () {
479+ if s .Calls [x ].DirSrc > r .Calls [x ].DirSrc {
469480 return true
470481 }
471482 if s .Calls [x ].Line < r .Calls [x ].Line {
472483 return true
473484 }
474485 if s .Calls [x ].Line > r .Calls [x ].Line {
486+ // ??
475487 return true
476488 }
477489 }
@@ -519,6 +531,9 @@ type Signature struct {
519531 Stack Stack
520532 // Locked is set if the goroutine was locked to an OS thread.
521533 Locked bool
534+
535+ // Disallow initialization with unnamed parameters.
536+ _ struct {}
522537}
523538
524539// equal returns true only if both signatures are exactly equal.
@@ -615,6 +630,9 @@ type Goroutine struct {
615630 ID int
616631 // First is the goroutine first printed, normally the one that crashed.
617632 First bool
633+
634+ // Disallow initialization with unnamed parameters.
635+ _ struct {}
618636}
619637
620638// Private stuff.
0 commit comments