2a208bc257
The gofrontend doesn't support the runtime.SetCgoTraceback function, which is specifically for handling mixed Go and C tracebacks. Use a build tag to avoid compiling the runtime/testdata/testprogcgo files that refer to SetCgoTraceback. These files are not currently compiled anyhow, but they will be with a future gotools patch. Reviewed-on: https://go-review.googlesource.com/46452 From-SVN: r249556
94 lines
2.0 KiB
C
94 lines
2.0 KiB
C
// Copyright 2016 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// The C definitions for tracebackctxt.go. That file uses //export so
|
|
// it can't put function definitions in the "C" import comment.
|
|
|
|
// +build !gccgo
|
|
|
|
#include <stdlib.h>
|
|
#include <stdint.h>
|
|
|
|
// Functions exported from Go.
|
|
extern void G1(void);
|
|
extern void G2(void);
|
|
|
|
void C1() {
|
|
G1();
|
|
}
|
|
|
|
void C2() {
|
|
G2();
|
|
}
|
|
|
|
struct cgoContextArg {
|
|
uintptr_t context;
|
|
};
|
|
|
|
struct cgoTracebackArg {
|
|
uintptr_t context;
|
|
uintptr_t sigContext;
|
|
uintptr_t* buf;
|
|
uintptr_t max;
|
|
};
|
|
|
|
struct cgoSymbolizerArg {
|
|
uintptr_t pc;
|
|
const char* file;
|
|
uintptr_t lineno;
|
|
const char* func;
|
|
uintptr_t entry;
|
|
uintptr_t more;
|
|
uintptr_t data;
|
|
};
|
|
|
|
// Uses atomic adds and subtracts to catch the possibility of
|
|
// erroneous calls from multiple threads; that should be impossible in
|
|
// this test case, but we check just in case.
|
|
static int contextCount;
|
|
|
|
int getContextCount() {
|
|
return __sync_add_and_fetch(&contextCount, 0);
|
|
}
|
|
|
|
void tcContext(void* parg) {
|
|
struct cgoContextArg* arg = (struct cgoContextArg*)(parg);
|
|
if (arg->context == 0) {
|
|
arg->context = __sync_add_and_fetch(&contextCount, 1);
|
|
} else {
|
|
if (arg->context != __sync_add_and_fetch(&contextCount, 0)) {
|
|
abort();
|
|
}
|
|
__sync_sub_and_fetch(&contextCount, 1);
|
|
}
|
|
}
|
|
|
|
void tcTraceback(void* parg) {
|
|
int base, i;
|
|
struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg);
|
|
if (arg->context == 0) {
|
|
// This shouldn't happen in this program.
|
|
abort();
|
|
}
|
|
// Return a variable number of PC values.
|
|
base = arg->context << 8;
|
|
for (i = 0; i < arg->context; i++) {
|
|
if (i < arg->max) {
|
|
arg->buf[i] = base + i;
|
|
}
|
|
}
|
|
}
|
|
|
|
void tcSymbolizer(void *parg) {
|
|
struct cgoSymbolizerArg* arg = (struct cgoSymbolizerArg*)(parg);
|
|
if (arg->pc == 0) {
|
|
return;
|
|
}
|
|
// Report two lines per PC returned by traceback, to test more handling.
|
|
arg->more = arg->file == NULL;
|
|
arg->file = "tracebackctxt.go";
|
|
arg->func = "cFunction";
|
|
arg->lineno = arg->pc + (arg->more << 16);
|
|
}
|