猿问

如何调试 C 共享库(用 Go 编写)——它挂在网络调用上

使用http.Post() 进行编码。如果我构建exe,就可以了。如果我构建 C 共享库-buildmode=c-shared,它会挂在 https.Post() 上。


我试过strace -fp PID:


futex(0x7f618b2c1cd0, FUTEX_WAKE, 1)    = 0

futex(0xc820022110, FUTEX_WAIT, 0, NULL

我试图添加分析器:


http.ListenAndServe("localhost:6060", nil)

http.Post()

但是它再次挂在 http.Post 上,并且分析器也被阻止了(它正在侦听,但不是来自 6060 端口的响应)。我已经发送了 SIGQUIT 信号 - 堆栈跟踪:


SIGQUIT: quit

PC=0x7f0cad5c9081 m=1


goroutine 0 [idle]:

runtime.futex(0xc820022110, 0x0, 0x0, 0x0, 0x7f0c00000000, 0x7f0cad577879, 0x0, 0x0, 0x7f0cad577ae8, 0xc820022110, ...)

        /usr/local/go/src/runtime/sys_linux_amd64.s:288 +0x21

runtime.futexsleep(0xc820022110, 0xc800000000, 0xffffffffffffffff)

        /usr/local/go/src/runtime/os1_linux.go:39 +0x53

runtime.notesleep(0xc820022110)

        /usr/local/go/src/runtime/lock_futex.go:142 +0xa8

runtime.stoplockedm()

        /usr/local/go/src/runtime/proc1.go:1268 +0xb2

runtime.schedule()

        /usr/local/go/src/runtime/proc1.go:1590 +0x72

runtime.park_m(0xc820000600)

        /usr/local/go/src/runtime/proc1.go:1698 +0x191

runtime.mcall(0x7f0cad5c722a)

        /usr/local/go/src/runtime/asm_amd64.s:204 +0x53


rax    0xca

rbx    0x0

rcx    0xffffffffffffffff

rdx    0x0

rdi    0xc820022110

rsi    0x0

rbp    0x1

rsp    0x7ffe7bc801a8

r8     0x0

r9     0x0

r10    0x0

r11    0x286

r12    0x4

r13    0x7f0cada47090

r14    0xd

r15    0x8

rip    0x7f0cad5c9081

rflags 0x286

cs     0x33

fs     0x0

gs     0x0

如何调试/解决这个问题?代码看起来不错 - 标准的可执行二进制文件返回正确的值。只有 C 共享库版本有一些问题。共享库中的另一种方法,不使用 http.post()/net.Dial() 是可以的。


原问题:https : //github.com/cavaliercoder/g2z/issues/5


慕容3067478
浏览 150回答 1
1回答

慕容森

好的,我为我的用例解决了这个问题,您可能处于类似的情况。当您将 Go 共享库链接到 C 或 C++ 应用程序时,Go 运行时会在您启动应用程序时加载(您可以验证这一点,func init()例如,在您启动应用程序时直接调用它)。然后,如果你 fork 一个进程并使用 Go 库,你将有不可预测的行为。基本上,你必须在 fork 之后加载 Go 共享库,并且一旦你 fork 就不能依赖它。使用dlopen和dlsym将允许您控制 Go 运行时何时被加载。
随时随地看视频慕课网APP

相关分类

Go
我要回答