英文:
Unable to get the stack trace with a corefile from a cgo routine when using golang
问题
我正在使用Golang和cgo。当我的C代码引发assert()
时,使用cgo
时无法看到C代码的堆栈跟踪。
相反,我看到捕获assert的golang运行时的堆栈跟踪。
这是我的C代码示例:
#include <stdio.h>
#include <pthread.h>
#include <assert.h>
#include <string.h>
void fn2(char *arg)
{
int stackvar2 = 256;
printf("Argument %s\n", arg);
assert(1 == 2);
}
void fn1(int arg)
{
int stackvar3 = 512;
char var[256];
strcpy(var, "deadbeef");
fn2(var);
}
void *thread(void *arg)
{
printf("Hello from the thread... going in for an assert\n");
fn1(1092);
return NULL;
}
void hello_world(char *str)
{
pthread_t tid;
printf("Hello World from C and here the str is from Go: %s\n", str);
pthread_create(&tid, NULL, thread, NULL);
sleep(100000);
}
这是我的Go代码:
package main
/*
extern void hello_world(char *str);
#cgo LDFLAGS: -L. -lhello
#cgo CFLAGS: -g3
*/
import "C"
import (
_ "fmt"
)
func main() {
str := "From Golang"
cStr := C.CString(str)
C.hello_world(cStr)
select {}
}
这是我的Makefile:
all:
gcc -g3 -O0 -c hello.c
ar cru libhello.a hello.o
go build hello.go
clean:
rm -f *.o hello
英文:
I am using Golang and cgo. When my C code raises an assert()
, I am unable to see the stack trace of the C code when using cgo
.
Instead, I see the stack trace of the golang runtime that caught the assert.
Here is an example of my C code
#include <stdio.h>
#include <pthread.h>
#include <assert.h>
#include <string.h>
void fn2(char *arg)
{
int stackvar2 = 256;
printf("Argument %s\n", arg);
assert(1 == 2);
}
void fn1(int arg)
{
int stackvar3 = 512;
char var[256];
strcpy(var, "deadbeef");
fn2(var);
}
void *thread(void *arg)
{
printf("Hello from the thread... going in for an assert\n");
fn1(1092);
return NULL;
}
void hello_world(char *str)
{
pthread_t tid;
printf("Hello World from C and here the str is from Go: %s\n", str);
pthread_create(&tid, NULL, thread, NULL);
sleep(100000);
}
Here is my Go code
package main
/*
extern void hello_world(char *str);
#cgo LDFLAGS: -L. -lhello
#cgo CFLAGS: -g3
*/
import "C"
import (
_ "fmt"
)
func main() {
str := "From Golang"
cStr := C.CString(str)
C.hello_world(cStr)
select {}
}
And here is my Makefile
all:
gcc -g3 -O0 -c hello.c
ar cru libhello.a hello.o
go build hello.go
clean:
rm -f *.o hello
答案1
得分: 2
除了显而易见的ulimit -c
检查之外,使用GOTRACEBACK=crash
运行Go程序。这将打印出更多信息,并允许程序使用SIGABRT
退出以触发核心转储。
英文:
Besides the obvious check of ulimit -c
, run the go program with GOTRACEBACK=crash
. This will print out more information, and allow the program to exit with SIGABRT
to trigger a core dump.
答案2
得分: 1
实际上,我需要将这段代码添加到我的Go代码中:signal.Ignore(syscall.SIGABRT)。这样可以让我查看崩溃的C代码的堆栈跟踪。
英文:
Actually I need to add this to my go code: signal.Ignore(syscall.SIGABRT). This allows me to see the stack trace of the C code that crashed.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论