Home | History | Annotate | Download | only in 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 // 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 }
     92