无法在使用golang时通过corefile从cgo例程中获取堆栈跟踪。

huangapple go评论106阅读模式
英文:

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代码示例:

  1. #include <stdio.h>
  2. #include <pthread.h>
  3. #include <assert.h>
  4. #include <string.h>
  5. void fn2(char *arg)
  6. {
  7. int stackvar2 = 256;
  8. printf("Argument %s\n", arg);
  9. assert(1 == 2);
  10. }
  11. void fn1(int arg)
  12. {
  13. int stackvar3 = 512;
  14. char var[256];
  15. strcpy(var, "deadbeef");
  16. fn2(var);
  17. }
  18. void *thread(void *arg)
  19. {
  20. printf("Hello from the thread... going in for an assert\n");
  21. fn1(1092);
  22. return NULL;
  23. }
  24. void hello_world(char *str)
  25. {
  26. pthread_t tid;
  27. printf("Hello World from C and here the str is from Go: %s\n", str);
  28. pthread_create(&tid, NULL, thread, NULL);
  29. sleep(100000);
  30. }

这是我的Go代码:

  1. package main
  2. /*
  3. extern void hello_world(char *str);
  4. #cgo LDFLAGS: -L. -lhello
  5. #cgo CFLAGS: -g3
  6. */
  7. import "C"
  8. import (
  9. _ "fmt"
  10. )
  11. func main() {
  12. str := "From Golang"
  13. cStr := C.CString(str)
  14. C.hello_world(cStr)
  15. select {}
  16. }

这是我的Makefile:

  1. all:
  2. gcc -g3 -O0 -c hello.c
  3. ar cru libhello.a hello.o
  4. go build hello.go
  5. clean:
  6. 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

  1. #include &lt;stdio.h&gt;
  2. #include &lt;pthread.h&gt;
  3. #include &lt;assert.h&gt;
  4. #include &lt;string.h&gt;
  5. void fn2(char *arg)
  6. {
  7. int stackvar2 = 256;
  8. printf(&quot;Argument %s\n&quot;, arg);
  9. assert(1 == 2);
  10. }
  11. void fn1(int arg)
  12. {
  13. int stackvar3 = 512;
  14. char var[256];
  15. strcpy(var, &quot;deadbeef&quot;);
  16. fn2(var);
  17. }
  18. void *thread(void *arg)
  19. {
  20. printf(&quot;Hello from the thread... going in for an assert\n&quot;);
  21. fn1(1092);
  22. return NULL;
  23. }
  24. void hello_world(char *str)
  25. {
  26. pthread_t tid;
  27. printf(&quot;Hello World from C and here the str is from Go: %s\n&quot;, str);
  28. pthread_create(&amp;tid, NULL, thread, NULL);
  29. sleep(100000);
  30. }
  31. Here is my Go code
  32. package main
  33. /*
  34. extern void hello_world(char *str);
  35. #cgo LDFLAGS: -L. -lhello
  36. #cgo CFLAGS: -g3
  37. */
  38. import &quot;C&quot;
  39. import (
  40. _ &quot;fmt&quot;
  41. )
  42. func main() {
  43. str := &quot;From Golang&quot;
  44. cStr := C.CString(str)
  45. C.hello_world(cStr)
  46. select {}
  47. }

And here is my Makefile

  1. all:
  2. gcc -g3 -O0 -c hello.c
  3. ar cru libhello.a hello.o
  4. go build hello.go
  5. clean:
  6. 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.

huangapple
  • 本文由 发表于 2016年2月6日 05:29:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/35233871.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定