...
Run Format

Text file src/runtime/testdata/testprogcgo/tracebackctxt_c.c

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	// 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	}

View as plain text