aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2016-05-04 13:27:27 -0700
committerIan Lance Taylor <iant@golang.org>2016-05-05 01:19:18 +0000
commit34f97d28d2ff435b8ac85ad6645aaf79a5d061bd (patch)
treed8f4c93afb50107b513e0f1b868a4fd33f39a4f3
parent57be1607d975ebec2f5faecea068f2db31abc041 (diff)
downloadgo-34f97d28d2ff435b8ac85ad6645aaf79a5d061bd.tar.gz
go-34f97d28d2ff435b8ac85ad6645aaf79a5d061bd.zip
runtime: put tracebackctxt C functions in .c file
Since tracebackctxt.go uses //export functions, the C functions can't be externally visible in the C comment. The code was using attributes to work around that, but that failed on Windows. Change-Id: If4449fd8209a8998b4f6855ea89e5db1471b2981 Reviewed-on: https://go-review.googlesource.com/22786 Reviewed-by: Minux Ma <minux@golang.org> Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org>
-rw-r--r--src/runtime/crash_cgo_test.go3
-rw-r--r--src/runtime/testdata/testprogcgo/tracebackctxt.go100
-rw-r--r--src/runtime/testdata/testprogcgo/tracebackctxt_c.c90
3 files changed, 98 insertions, 95 deletions
diff --git a/src/runtime/crash_cgo_test.go b/src/runtime/crash_cgo_test.go
index cb46c2a5dc..c34c629b9c 100644
--- a/src/runtime/crash_cgo_test.go
+++ b/src/runtime/crash_cgo_test.go
@@ -225,9 +225,6 @@ func TestCgoCrashTraceback(t *testing.T) {
}
func TestCgoTracebackContext(t *testing.T) {
- if runtime.GOOS == "windows" {
- t.Skipf("test does not work on %s/%s", runtime.GOOS, runtime.GOARCH)
- }
got := runTestProg(t, "testprogcgo", "TracebackContext")
want := "OK\n"
if got != want {
diff --git a/src/runtime/testdata/testprogcgo/tracebackctxt.go b/src/runtime/testdata/testprogcgo/tracebackctxt.go
index 4b2e486304..51fa4ad25c 100644
--- a/src/runtime/testdata/testprogcgo/tracebackctxt.go
+++ b/src/runtime/testdata/testprogcgo/tracebackctxt.go
@@ -1,106 +1,22 @@
-// Copyright 2016 The Go Authors. All rights reserved.
+// 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 __attribute__((weak)) used below doesn't seem to work on Windows.
-// +build !windows
-
package main
// Test the context argument to SetCgoTraceback.
// Use fake context, traceback, and symbolizer functions.
/*
-#include <stdlib.h>
-#include <stdint.h>
-
-// Use weak declarations so that we can define functions here even
-// though we use //export in the Go code.
-extern void tcContext(void*) __attribute__((weak));
-extern void tcTraceback(void*) __attribute__((weak));
-extern void tcSymbolizer(void*) __attribute__((weak));
-
-extern void G1(void);
-extern void G2(void);
-
-static void C1() {
- G1();
-}
-
-static void C2() {
- G2();
-}
-
-struct cgoContextArg {
- uintptr_t context;
-};
-
-struct cgoTracebackArg {
- uintptr_t context;
- 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;
-};
-
-// Global so that there is only one, weak so that //export works.
-// 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.
-int contextCount __attribute__((weak));
-
-static 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);
-}
+// Defined in tracebackctxt_c.c.
+extern void C1(void);
+extern void C2(void);
+extern void tcContext(void*);
+extern void tcTraceback(void*);
+extern void tcSymbolizer(void*);
+extern int getContextCount(void);
*/
import "C"
diff --git a/src/runtime/testdata/testprogcgo/tracebackctxt_c.c b/src/runtime/testdata/testprogcgo/tracebackctxt_c.c
new file mode 100644
index 0000000000..bbac39658e
--- /dev/null
+++ b/src/runtime/testdata/testprogcgo/tracebackctxt_c.c
@@ -0,0 +1,90 @@
+// 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.
+
+#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* 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);
+}