]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: put tracebackctxt C functions in .c file
authorIan Lance Taylor <iant@golang.org>
Wed, 4 May 2016 20:27:27 +0000 (13:27 -0700)
committerIan Lance Taylor <iant@golang.org>
Thu, 5 May 2016 01:19:18 +0000 (01:19 +0000)
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>

src/runtime/crash_cgo_test.go
src/runtime/testdata/testprogcgo/tracebackctxt.go
src/runtime/testdata/testprogcgo/tracebackctxt_c.c [new file with mode: 0644]

index cb46c2a5dc71f6caeca69c4f40d65029dac6cfef..c34c629b9c6a01dab1685636fb245451d1b7d826 100644 (file)
@@ -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 {
index 4b2e4863044dfd1b5176f1ab333754485213d87f..51fa4ad25c320f357a7b466009787e584664089c 100644 (file)
-// 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 (file)
index 0000000..bbac396
--- /dev/null
@@ -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);
+}