...

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.
    12extern void G1(void);
    13extern void G2(void);
    14extern void TracebackContextPreemptionGoFunction(int);
    15extern void TracebackContextProfileGoFunction(void);
    16
    17void C1() {
    18	G1();
    19}
    20
    21void C2() {
    22	G2();
    23}
    24
    25struct cgoContextArg {
    26	uintptr_t context;
    27};
    28
    29struct cgoTracebackArg {
    30	uintptr_t  context;
    31	uintptr_t  sigContext;
    32	uintptr_t* buf;
    33	uintptr_t  max;
    34};
    35
    36struct 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.
    49static int contextCount;
    50
    51int getContextCount() {
    52	return __sync_add_and_fetch(&contextCount, 0);
    53}
    54
    55void tcContext(void* parg) {
    56	struct cgoContextArg* arg = (struct cgoContextArg*)(parg);
    57	if (arg->context == 0) {
    58		arg->context = __sync_add_and_fetch(&contextCount, 1);
    59	} else {
    60		if (arg->context != __sync_add_and_fetch(&contextCount, 0)) {
    61			abort();
    62		}
    63		__sync_sub_and_fetch(&contextCount, 1);
    64	}
    65}
    66
    67void tcContextSimple(void* parg) {
    68	struct cgoContextArg* arg = (struct cgoContextArg*)(parg);
    69	if (arg->context == 0) {
    70		arg->context = 1;
    71	}
    72}
    73
    74void tcTraceback(void* parg) {
    75	int base, i;
    76	struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg);
    77	if (arg->context == 0 && arg->sigContext == 0) {
    78		// This shouldn't happen in this program.
    79		abort();
    80	}
    81	// Return a variable number of PC values.
    82	base = arg->context << 8;
    83	for (i = 0; i < arg->context; i++) {
    84		if (i < arg->max) {
    85			arg->buf[i] = base + i;
    86		}
    87	}
    88}
    89
    90void tcSymbolizer(void *parg) {
    91	struct cgoSymbolizerArg* arg = (struct cgoSymbolizerArg*)(parg);
    92	if (arg->pc == 0) {
    93		return;
    94	}
    95	// Report two lines per PC returned by traceback, to test more handling.
    96	arg->more = arg->file == NULL;
    97	arg->file = "tracebackctxt.go";
    98	arg->func = "cFunction";
    99	arg->lineno = arg->pc + (arg->more << 16);
   100}
   101
   102void TracebackContextPreemptionCallGo(int i) {
   103	TracebackContextPreemptionGoFunction(i);
   104}
   105
   106void TracebackContextProfileCallGo(void) {
   107	TracebackContextProfileGoFunction();
   108}

View as plain text