...

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

Documentation: runtime/testdata/testprogcgo

     1  // Copyright 2016 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  // Test the context argument to SetCgoTraceback.
     8  // Use fake context, traceback, and symbolizer functions.
     9  
    10  /*
    11  // Defined in tracebackctxt_c.c.
    12  extern void C1(void);
    13  extern void C2(void);
    14  extern void tcContext(void*);
    15  extern void tcContextSimple(void*);
    16  extern void tcTraceback(void*);
    17  extern void tcSymbolizer(void*);
    18  extern int getContextCount(void);
    19  extern void TracebackContextPreemptionCallGo(int);
    20  */
    21  import "C"
    22  
    23  import (
    24  	"fmt"
    25  	"runtime"
    26  	"sync"
    27  	"unsafe"
    28  )
    29  
    30  func init() {
    31  	register("TracebackContext", TracebackContext)
    32  	register("TracebackContextPreemption", TracebackContextPreemption)
    33  }
    34  
    35  var tracebackOK bool
    36  
    37  func TracebackContext() {
    38  	runtime.SetCgoTraceback(0, unsafe.Pointer(C.tcTraceback), unsafe.Pointer(C.tcContext), unsafe.Pointer(C.tcSymbolizer))
    39  	C.C1()
    40  	if got := C.getContextCount(); got != 0 {
    41  		fmt.Printf("at end contextCount == %d, expected 0\n", got)
    42  		tracebackOK = false
    43  	}
    44  	if tracebackOK {
    45  		fmt.Println("OK")
    46  	}
    47  }
    48  
    49  //export G1
    50  func G1() {
    51  	C.C2()
    52  }
    53  
    54  //export G2
    55  func G2() {
    56  	pc := make([]uintptr, 32)
    57  	n := runtime.Callers(0, pc)
    58  	cf := runtime.CallersFrames(pc[:n])
    59  	var frames []runtime.Frame
    60  	for {
    61  		frame, more := cf.Next()
    62  		frames = append(frames, frame)
    63  		if !more {
    64  			break
    65  		}
    66  	}
    67  
    68  	want := []struct {
    69  		function string
    70  		line     int
    71  	}{
    72  		{"main.G2", 0},
    73  		{"cFunction", 0x10200},
    74  		{"cFunction", 0x200},
    75  		{"cFunction", 0x10201},
    76  		{"cFunction", 0x201},
    77  		{"main.G1", 0},
    78  		{"cFunction", 0x10100},
    79  		{"cFunction", 0x100},
    80  		{"main.TracebackContext", 0},
    81  	}
    82  
    83  	ok := true
    84  	i := 0
    85  wantLoop:
    86  	for _, w := range want {
    87  		for ; i < len(frames); i++ {
    88  			if w.function == frames[i].Function {
    89  				if w.line != 0 && w.line != frames[i].Line {
    90  					fmt.Printf("found function %s at wrong line %#x (expected %#x)\n", w.function, frames[i].Line, w.line)
    91  					ok = false
    92  				}
    93  				i++
    94  				continue wantLoop
    95  			}
    96  		}
    97  		fmt.Printf("did not find function %s in\n", w.function)
    98  		for _, f := range frames {
    99  			fmt.Println(f)
   100  		}
   101  		ok = false
   102  		break
   103  	}
   104  	tracebackOK = ok
   105  	if got := C.getContextCount(); got != 2 {
   106  		fmt.Printf("at bottom contextCount == %d, expected 2\n", got)
   107  		tracebackOK = false
   108  	}
   109  }
   110  
   111  // Issue 47441.
   112  func TracebackContextPreemption() {
   113  	runtime.SetCgoTraceback(0, unsafe.Pointer(C.tcTraceback), unsafe.Pointer(C.tcContextSimple), unsafe.Pointer(C.tcSymbolizer))
   114  
   115  	const funcs = 10
   116  	const calls = 1e5
   117  	var wg sync.WaitGroup
   118  	for i := 0; i < funcs; i++ {
   119  		wg.Add(1)
   120  		go func(i int) {
   121  			defer wg.Done()
   122  			for j := 0; j < calls; j++ {
   123  				C.TracebackContextPreemptionCallGo(C.int(i*calls + j))
   124  			}
   125  		}(i)
   126  	}
   127  	wg.Wait()
   128  
   129  	fmt.Println("OK")
   130  }
   131  
   132  //export TracebackContextPreemptionGoFunction
   133  func TracebackContextPreemptionGoFunction(i C.int) {
   134  	// Do some busy work.
   135  	fmt.Sprintf("%d\n", i)
   136  }
   137  

View as plain text