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