...
Run Format

Source file src/runtime/testdata/testprogcgo/tracebackctxt.go

Documentation: runtime/testdata/testprogcgo

  // Copyright 2016 The Go Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  // The __attribute__((weak)) used below doesn't seem to work on Windows.
  
  package main
  
  // Test the context argument to SetCgoTraceback.
  // Use fake context, traceback, and symbolizer functions.
  
  /*
  // Defined in tracebackctxt_c.c.
  extern void C1(void);
  extern void C2(void);
  extern void tcContext(void*);
  extern void tcTraceback(void*);
  extern void tcSymbolizer(void*);
  extern int getContextCount(void);
  */
  import "C"
  
  import (
  	"fmt"
  	"runtime"
  	"unsafe"
  )
  
  func init() {
  	register("TracebackContext", TracebackContext)
  }
  
  var tracebackOK bool
  
  func TracebackContext() {
  	runtime.SetCgoTraceback(0, unsafe.Pointer(C.tcTraceback), unsafe.Pointer(C.tcContext), unsafe.Pointer(C.tcSymbolizer))
  	C.C1()
  	if got := C.getContextCount(); got != 0 {
  		fmt.Printf("at end contextCount == %d, expected 0\n", got)
  		tracebackOK = false
  	}
  	if tracebackOK {
  		fmt.Println("OK")
  	}
  }
  
  //export G1
  func G1() {
  	C.C2()
  }
  
  //export G2
  func G2() {
  	pc := make([]uintptr, 32)
  	n := runtime.Callers(0, pc)
  	cf := runtime.CallersFrames(pc[:n])
  	var frames []runtime.Frame
  	for {
  		frame, more := cf.Next()
  		frames = append(frames, frame)
  		if !more {
  			break
  		}
  	}
  
  	want := []struct {
  		function string
  		line     int
  	}{
  		{"main.G2", 0},
  		{"cFunction", 0x10200},
  		{"cFunction", 0x200},
  		{"cFunction", 0x10201},
  		{"cFunction", 0x201},
  		{"main.G1", 0},
  		{"cFunction", 0x10100},
  		{"cFunction", 0x100},
  		{"main.TracebackContext", 0},
  	}
  
  	ok := true
  	i := 0
  wantLoop:
  	for _, w := range want {
  		for ; i < len(frames); i++ {
  			if w.function == frames[i].Function {
  				if w.line != 0 && w.line != frames[i].Line {
  					fmt.Printf("found function %s at wrong line %#x (expected %#x)\n", w.function, frames[i].Line, w.line)
  					ok = false
  				}
  				i++
  				continue wantLoop
  			}
  		}
  		fmt.Printf("did not find function %s in\n", w.function)
  		for _, f := range frames {
  			fmt.Println(f)
  		}
  		ok = false
  		break
  	}
  	tracebackOK = ok
  	if got := C.getContextCount(); got != 2 {
  		fmt.Printf("at bottom contextCount == %d, expected 2\n", got)
  		tracebackOK = false
  	}
  }
  

View as plain text