Golang Go语言编译成C shared库使用luaffi load会死锁

Golang Go语言编译成C shared库使用luaffi load会死锁

export go 函数然后编译成 c 动态库,这里完美注意了 cgo 的内存搬运问题。

go build -o iface.so -buildmode=c-shared -ldflags "-w -s" iface.go

然后在 OpenResty 下用 luaffi load 这个动态库,平时使用没什么问题。最近发现在 reload 比较频繁下会偶发 reload 卡住。

上去用 gdb -p <nginx master="" pid=""></nginx>

bt 当前栈顶在这个 go 动态库中,由于没有调试符号,只能反汇编。

diss/r $rip,查看 syscall 前的 rax 值,发现当前 master 阻塞在 futex syscall 上,发生了死锁。


更多关于Golang Go语言编译成C shared库使用luaffi load会死锁的实战教程也可以访问 https://www.itying.com/category-94-b0.html

5 回复

还能这么玩儿,mark 一下

更多关于Golang Go语言编译成C shared库使用luaffi load会死锁的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


把 -ldflags “-w -s” 去掉就有符号了,挂上去调试吧

fork+多线程会有很多 bug

reload 时动态是否有变化,如果有变化容易出现问题

在将Golang代码编译为C共享库并使用luaffi加载时遇到死锁问题,通常涉及多线程和锁机制的复杂交互。这里有几个可能的解决方向和检查点:

  1. 确保Golang运行时初始化:在使用Golang编译的C共享库时,确保正确初始化Golang运行时(runtime)。这通常包括在库的初始化函数中调用runtime.LockOSThread()runtime.GOMAXPROCS(1)来避免不必要的线程切换和调度问题。

  2. 检查luaffi与Golang的交互luaffi是一个用于Lua的FFI库,它允许从Lua调用C函数。确保所有通过luaffi调用的Golang函数都是线程安全的,特别是那些可能涉及全局变量或共享资源的函数。

  3. 避免死锁:检查Golang代码中是否存在可能导致死锁的同步原语(如sync.Mutexsync.WaitGroup等)的不当使用。确保所有锁在适当的时候被获取和释放。

  4. 调试和日志:增加日志输出,特别是在进入和离开可能涉及锁的代码块时。这可以帮助识别死锁发生的具体位置。

  5. 考虑使用通道:如果可能,使用Golang的通道(channels)进行线程间通信,因为它们天生就是设计来避免死锁的。

如果问题依旧存在,建议创建一个最小化的可复现问题的示例,并寻求来自Golang和luaffi社区的更具体帮助。

回到顶部