github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/src/runtime/testdata/testprogcgo/tracebackctxt_c.c (about) 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 // The C definitions for tracebackctxt.go. That file uses //export so 6 // it can't put function definitions in the "C" import comment. 7 8 #include <stdlib.h> 9 #include <stdint.h> 10 11 // Functions exported from Go. 12 extern void G1(void); 13 extern void G2(void); 14 15 void C1() { 16 G1(); 17 } 18 19 void C2() { 20 G2(); 21 } 22 23 struct cgoContextArg { 24 uintptr_t context; 25 }; 26 27 struct cgoTracebackArg { 28 uintptr_t context; 29 uintptr_t sigContext; 30 uintptr_t* buf; 31 uintptr_t max; 32 }; 33 34 struct cgoSymbolizerArg { 35 uintptr_t pc; 36 const char* file; 37 uintptr_t lineno; 38 const char* func; 39 uintptr_t entry; 40 uintptr_t more; 41 uintptr_t data; 42 }; 43 44 // Uses atomic adds and subtracts to catch the possibility of 45 // erroneous calls from multiple threads; that should be impossible in 46 // this test case, but we check just in case. 47 static int contextCount; 48 49 int getContextCount() { 50 return __sync_add_and_fetch(&contextCount, 0); 51 } 52 53 void tcContext(void* parg) { 54 struct cgoContextArg* arg = (struct cgoContextArg*)(parg); 55 if (arg->context == 0) { 56 arg->context = __sync_add_and_fetch(&contextCount, 1); 57 } else { 58 if (arg->context != __sync_add_and_fetch(&contextCount, 0)) { 59 abort(); 60 } 61 __sync_sub_and_fetch(&contextCount, 1); 62 } 63 } 64 65 void tcTraceback(void* parg) { 66 int base, i; 67 struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg); 68 if (arg->context == 0) { 69 // This shouldn't happen in this program. 70 abort(); 71 } 72 // Return a variable number of PC values. 73 base = arg->context << 8; 74 for (i = 0; i < arg->context; i++) { 75 if (i < arg->max) { 76 arg->buf[i] = base + i; 77 } 78 } 79 } 80 81 void tcSymbolizer(void *parg) { 82 struct cgoSymbolizerArg* arg = (struct cgoSymbolizerArg*)(parg); 83 if (arg->pc == 0) { 84 return; 85 } 86 // Report two lines per PC returned by traceback, to test more handling. 87 arg->more = arg->file == NULL; 88 arg->file = "tracebackctxt.go"; 89 arg->func = "cFunction"; 90 arg->lineno = arg->pc + (arg->more << 16); 91 }