记录一次C语言调用go生成的动态库的踩坑过程
发布网友
发布时间:2024-10-19 23:01
我来回答
共1个回答
热心网友
时间:2024-11-02 23:20
遇到问题后,通过查看调用栈信息,发现程序卡死现象出现在调用go生成的动态库期间。起初,对go语言不熟悉,无法判断问题所在。尝试在互联网上查找相关资料,但未能找到具体解决方法。最终,参考stackoverflow上的类似问题解答,发现原因可能与go运行时环境的创建相关。
go语言在启动时会创建特定的运行时线程,用于执行诸如垃圾回收(GC)等操作。当新程序在子进程中调用go生成的动态库时,父进程在fork子进程时,并不会复制这些运行时线程至子进程。因此,当子进程中重新调用dlopen打开go生成的动态库时,无法重新创建所需的运行时线程,导致go中涉及运行时程序干预的代码无法正常运行,如GC操作。这引起go程序进入死循环状态,导致程序卡死。
解决方法是在fork之后运行dlopen打开go生成的动态库,以确保子进程能够创建所需的运行时线程。修改后,程序运行时的线程信息显示,新增了多个runtime.futex线程,这些线程正是go程序运行时所需。对比修改前的线程信息,发现差异在于运行时线程的创建。之前的程序没有遇到此问题,是因为它们在启动时并未使用fork操作。
对于触发GC时导致go程序无法运行的原因,需要深入了解go的垃圾回收机制。虽然已通过stackoverflow上的信息了解到问题大体原因,但对于GC细节的解释仍需更多go语言方面的知识。此问题的解决,不仅解决了当前卡死的程序问题,还增进了对go动态库调用机制的理解。