欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C語言調(diào)用go生成的動(dòng)態(tài)庫的踩坑過程解析

 更新時(shí)間:2023年09月07日 11:15:02   作者:viyon  
這篇文章主要為大家介紹了C語言調(diào)用go生成的動(dòng)態(tài)庫的踩坑過程解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

C語言調(diào)用go生成動(dòng)態(tài)庫踩坑過程解析

問題現(xiàn)象

由于某些特殊原因,需要在C語言中調(diào)用go語言生成的so,本來挺順利,一切都運(yùn)行的很好。突然某一天,不知道怎么回事,再一個(gè)新程序中無法正常運(yùn)行了,看到的現(xiàn)象是程序無任何響應(yīng),類似于直接卡死了。使用gdb查看進(jìn)程當(dāng)前的信息,看到如下調(diào)用棧:

(gdb) source /root/go/src/runtime/runtime-gdb.py
Loading Go Runtime support.
(gdb) bt
#0 runtime.futex () at /usr/local/go/src/runtime/sys_linux_amd64.s:520
#1 0x00007fff23c550f6 in runtime.futexsleep (addr=0xfffffffffffffe00, val=0, ns=140733793710979) at /usr/local/go/src/runtime/os_linux.go:44
#2 0x00007fff23c35667 in runtime.notetsleep_internal (n=0x7fff23dc66e8 <runtime.work+232>, ns=-1) at /usr/local/go/src/runtime/lock_futex.go:183
#3 0x00007fff23c35785 in runtime.notetsleepg (n=0x7fff23dc66e8 <runtime.work+232>, ns=-1) at /usr/local/go/src/runtime/lock_futex.go:237
#4 0x00007fff23c41338 in runtime.gcBgMarkStartWorkers () at /usr/local/go/src/runtime/mgc.go:1126
#5 0x00007fff23c3fd92 in runtime.gcStart (trigger=...) at /usr/local/go/src/runtime/mgc.go:637
#6 0x00007fff23c36e3d in runtime.mallocgc (size=565248, typ=0x7fff23cfd160, needzero=true) at /usr/local/go/src/runtime/malloc.go:1174
#7 0x00007fff23c6dfaa in runtime.growslice (et=, old=..., cap=) at /usr/local/go/src/runtime/slice.go:267
#8 0x00007fff23c918ef in regexp/syntax.(*compiler).inst (c=0xc000044bf8, op=) at /usr/local/go/src/regexp/syntax/compile.go:164
#9 regexp/syntax.(*compiler).rune (c=0xc000044bf8, r=[]int32 = {...}, flags=212) at /usr/local/go/src/regexp/syntax/compile.go:273
#10 0x00007fff23c90f1e in regexp/syntax.(*compiler).compile (c=0xc000044bf8, re=0xc000190000) at /usr/local/go/src/regexp/syntax/compile.go:101
#11 0x00007fff23c8f805 in regexp/syntax.Compile (re=0xc000190000) at /usr/local/go/src/regexp/syntax/compile.go:74
#12 0x00007fff23ca4a9a in regexp.compile (expr=,
mode=, longest=false) at /usr/local/go/src/regexp/regexp.go:178
#13 0x00007fff23ca5591 in regexp.Compile (expr="") at /usr/local/go/src/regexp/regexp.go:133
#14 regexp.MustCompile (str="") at /usr/local/go/src/regexp/regexp.go:309
#15 0x00007fff23ca8e0a in main.CheckPostAddress (buf=, bufLen=) at /root/codes/di_rechk/rechk.go:540
#16 0x00007fff23ca9a88 in _cgoexp_67df0785bef2_CheckPostAddress (a=0x7fffffffc740) at _cgo_gotypes.go:162
#17 0x00007fff23c2e21a in runtime.cgocallbackg1 (fn=0x7fff23ca9a60 <_cgoexp_67df0785bef2_CheckPostAddress>, frame=0x7fffffffc740, ctxt=0)
at /usr/local/go/src/runtime/cgocall.go:306
#18 0x00007fff23c2dee9 in runtime.cgocallbackg (fn=0x7fff23ca9a60 <_cgoexp_67df0785bef2_CheckPostAddress>, frame=0x7fffffffc740, ctxt=0)
at /usr/local/go/src/runtime/cgocall.go:232
#19 0x00007fff23c83791 in runtime.cgocallbackg (fn=0x7fff23ca9a60 <_cgoexp_67df0785bef2_CheckPostAddress>, frame=0x7fffffffc740, ctxt=0)
at :1
#20 0x00007fff23c813f3 in runtime.cgocallback () at /usr/local/go/src/runtime/asm_amd64.s:915
#21 0x00007fff23c81601 in runtime.goexit () at /usr/local/go/src/runtime/asm_amd64.s:1581
#22 0x0000000000000000 in ?? ()
(gdb) info goroutines
    17 syscall runtime.notetsleepg
    2 waiting runtime.gopark
    3 waiting runtime.gopark
    4 waiting runtime.gopark
    19 runnable runtime.gcBgMarkWorker
(gdb) goroutine 17 bt
#0 runtime.notetsleepg (n=0x7fff23dc66e8 <runtime.work+232>, ns=-1) at /usr/local/go/src/runtime/lock_futex.go:237
#1 0x00007fff23c41338 in runtime.gcBgMarkStartWorkers () at /usr/local/go/src/runtime/mgc.go:1126
#2 0x00007fff23c3fd92 in runtime.gcStart (trigger=...) at /usr/local/go/src/runtime/mgc.go:637
#3 0x00007fff23c36e3d in runtime.mallocgc (size=565248, typ=0x7fff23cfd160, needzero=true) at /usr/local/go/src/runtime/malloc.go:1174
#4 0x00007fff23c6dfaa in runtime.growslice (et=, old=..., cap=) at /usr/local/go/src/runtime/slice.go:267
#5 0x00007fff23c918ef in regexp/syntax.(*compiler).inst (c=0xc000044bf8, op=) at /usr/local/go/src/regexp/syntax/compile.go:164
#6 regexp/syntax.(*compiler).rune (c=0xc000044bf8, r=[]int32 = {...}, flags=212) at /usr/local/go/src/regexp/syntax/compile.go:273
#7 0x00007fff23c90f1e in regexp/syntax.(*compiler).compile (c=0xc000044bf8, re=0xc00022a000) at /usr/local/go/src/regexp/syntax/compile.go:101
#8 0x00007fff23c8f805 in regexp/syntax.Compile (re=0xc00022a000) at /usr/local/go/src/regexp/syntax/compile.go:74
#9 0x00007fff23ca4a9a in regexp.compile (expr=,
mode=, longest=false) at /usr/local/go/src/regexp/regexp.go:178
#10 0x00007fff23ca5591 in regexp.Compile (expr=""") at /usr/local/go/src/regexp/regexp.go:133
#11 regexp.MustCompile (str=""") at /usr/local/go/src/regexp/regexp.go:309
#12 0x00007fff23ca8e0a in main.CheckPostAddress (buf=, bufLen=) at /root/codes/di_rechk/rechk.go:540
#13 0x00007fff23ca9a88 in _cgoexp_67df0785bef2_CheckPostAddress (a=0x7fffffffc740) at _cgo_gotypes.go:162
#14 0x00007fff23c2e21a in runtime.cgocallbackg1 (fn=0x7fff23ca9a60 <_cgoexp_67df0785bef2_CheckPostAddress>, frame=0x7fffffffc740, ctxt=0)
at /usr/local/go/src/runtime/cgocall.go:306
#15 0x00007fff23c2dee9 in runtime.cgocallbackg (fn=0x7fff23ca9a60 <_cgoexp_67df0785bef2_CheckPostAddress>, frame=0x7fffffffc740, ctxt=0)
at /usr/local/go/src/runtime/cgocall.go:232
#16 0x00007fff23c83791 in runtime.cgocallbackg (fn=0x7fff23ca9a60 <_cgoexp_67df0785bef2_CheckPostAddress>, frame=0x7fffffffc740, ctxt=0)
at :1
#17 0x00007fff23c813f3 in runtime.cgocallback () at /usr/local/go/src/runtime/asm_amd64.s:915
#18 0x00007fff23c81601 in runtime.goexit () at /usr/local/go/src/runtime/asm_amd64.s:1581
#19 0x0000000000000000 in ?? ()
(gdb) goroutine 2 bt
#0 runtime.gopark (unlockf=, lock=, reason=, traceEv=, traceskip=)
at /usr/local/go/src/runtime/proc.go:367
#1 0x00007fff23c5b86d in runtime.goparkunlock (reason=, traceEv=, traceskip=, lock=)
at /usr/local/go/src/runtime/proc.go:372
#2 runtime.forcegchelper () at /usr/local/go/src/runtime/proc.go:306
#3 0x00007fff23c81601 in runtime.goexit () at /usr/local/go/src/runtime/asm_amd64.s:1581
#4 0x0000000000000000 in ?? ()
(gdb) goroutine 3 bt
#0 runtime.gopark (unlockf=, lock=, reason=, traceEv=, traceskip=)
at /usr/local/go/src/runtime/proc.go:367
#1 0x00007fff23c48ee8 in runtime.goparkunlock (reason=, traceEv=, traceskip=, lock=)
at /usr/local/go/src/runtime/proc.go:372
#2 runtime.bgsweep () at /usr/local/go/src/runtime/mgcsweep.go:163
#3 0x00007fff23c81601 in runtime.goexit () at /usr/local/go/src/runtime/asm_amd64.s:1581
#4 0x0000000000000000 in ?? ()
(gdb) goroutine 4 bt
#0 runtime.gopark (unlockf=, lock=, reason=, traceEv=, traceskip=)
at /usr/local/go/src/runtime/proc.go:367
#1 0x00007fff23c46fed in runtime.goparkunlock (reason=, traceEv=, traceskip=, lock=)
at /usr/local/go/src/runtime/proc.go:372
#2 runtime.bgscavenge () at /usr/local/go/src/runtime/mgcscavenge.go:265
#3 0x00007fff23c81601 in runtime.goexit () at /usr/local/go/src/runtime/asm_amd64.s:1581
#4 0x0000000000000000 in ?? ()
(gdb) goroutine 19 bt
#0 runtime.gcBgMarkWorker () at /usr/local/go/src/runtime/mgc.go:1166
#1 0x00007fff23c81601 in runtime.goexit () at /usr/local/go/src/runtime/asm_amd64.s:1581
#2 0x0000000000000000 in ?? ()
(gdb) info threads
Id Target Id Frame
1 Thread 0x7ffff7966b80 (LWP 2024707) "nginx" runtime.futex () at /usr/local/go/src/runtime/sys_linux_amd64.s:520
2 Thread 0x7ffef1ffb700 (LWP 2024717) "nginx" 0x00007ffff7a483bf in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0,
    req=req@entry=0x7ffef1ffae80, rem=rem@entry=0x0) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
3 Thread 0x7ffef27fc700 (LWP 2024718) "ZMQbg/Reaper" 0x00007ffff7a8a5ce in epoll_wait (epfd=42, events=events@entry=0x7ffef27fb200,
    maxevents=maxevents@entry=256, timeout=timeout@entry=-1) at ../sysdeps/unix/sysv/linux/epoll_wait.c:30
4 Thread 0x7ffef2ffd700 (LWP 2024719) "ZMQbg/IO/0" 0x00007ffff7a8a5ce in epoll_wait (epfd=44, events=events@entry=0x7ffef2ffc200,
    maxevents=maxevents@entry=256, timeout=timeout@entry=-1) at ../sysdeps/unix/sysv/linux/epoll_wait.c:30

問題解決過程

由于對go不太熟悉,所以不知道出了什么問題。go本身的代碼也比較簡單,沒有太復(fù)雜的操作。而且之前的程序調(diào)用這些go代碼生成的so,也能整成運(yùn)行。從網(wǎng)上查資料也是一頭霧水,不知道該怎么查。經(jīng)過一段時(shí)間的搜索,終于在stackoverflow中看到了一個(gè)類似問題。按照這個(gè)原因進(jìn)行修改,果然修改好了。

問題原因總結(jié)

按照stackoverflow中的總結(jié)。原因是在程序啟動(dòng)的時(shí)候,如果調(diào)用了go生成的so,那么go會(huì)調(diào)用一些函數(shù)建立go運(yùn)行時(shí)環(huán)境,會(huì)創(chuàng)建一些線程。而我的新程序中,具體調(diào)用go函數(shù)的地方,是在子進(jìn)程中調(diào)用的,而父進(jìn)程fork子進(jìn)程的時(shí)候,不會(huì)把go建立的那幾個(gè)運(yùn)行時(shí)線程復(fù)制到子進(jìn)程中,即便在子進(jìn)程中重新dlopen go生成的so也不會(huì)重新創(chuàng)建那幾個(gè)運(yùn)行時(shí)線程,所以導(dǎo)致go中那些涉及到一些需要運(yùn)行時(shí)程序干預(yù)的代碼(如gc等)無法正常運(yùn)行。而我的go代碼中剛好觸發(fā)了GC,導(dǎo)致go無法運(yùn)行,一直處在死循環(huán)之中。

解決方法是:在fork之后運(yùn)行dlopen打開go生成的so,這樣就可以了。

修改之后,程序運(yùn)行的信息如下:

(gdb) info threads
  Id   Target Id                                          Frame
* 1    Thread 0x7ffff7966b80 (LWP 2366880) "nginx"        0x00007ffff7a8a5ce in epoll_wait (epfd=31, events=0x555555d0af90, maxevents=512,
    timeout=timeout@entry=-1) at ../sysdeps/unix/sysv/linux/epoll_wait.c:30
  2    Thread 0x7fff481fd700 (LWP 2366893) "nginx"        0x00007ffff7a483bf in __GI___clock_nanosleep (clock_id=clock_id@entry=0, flags=flags@entry=0,
    req=req@entry=0x7fff481fce80, rem=rem@entry=0x0) at ../sysdeps/unix/sysv/linux/clock_nanosleep.c:78
  3    Thread 0x7fff489fe700 (LWP 2366894) "ZMQbg/Reaper" 0x00007ffff7a8a5ce in epoll_wait (epfd=42, events=events@entry=0x7fff489fd200,
    maxevents=maxevents@entry=256, timeout=timeout@entry=-1) at ../sysdeps/unix/sysv/linux/epoll_wait.c:30
  4    Thread 0x7fff491ff700 (LWP 2366895) "ZMQbg/IO/0"   0x00007ffff7a8a5ce in epoll_wait (epfd=44, events=events@entry=0x7fff491fe200,
    maxevents=maxevents@entry=256, timeout=timeout@entry=-1) at ../sysdeps/unix/sysv/linux/epoll_wait.c:30
  5    Thread 0x7fff245cb700 (LWP 2368456) "nginx"        runtime.futex () at /root/go/src/runtime/sys_linux_amd64.s:560
  6    Thread 0x7fff20c34700 (LWP 2368457) "nginx"        runtime.futex () at /root/go/src/runtime/sys_linux_amd64.s:560
  7    Thread 0x7fff091a1700 (LWP 2368458) "nginx"        runtime.futex () at /root/go/src/runtime/sys_linux_amd64.s:560
  8    Thread 0x7fff089a0700 (LWP 2368459) "nginx"        runtime.futex () at /root/go/src/runtime/sys_linux_amd64.s:560
  9    Thread 0x7ffed7fff700 (LWP 2368460) "nginx"        runtime.futex () at /root/go/src/runtime/sys_linux_amd64.s:560
  10   Thread 0x7ffed77fe700 (LWP 2368461) "nginx"        runtime.futex () at /root/go/src/runtime/sys_linux_amd64.s:560
  11   Thread 0x7ffed6ffd700 (LWP 2368462) "nginx"        runtime.futex () at /root/go/src/runtime/sys_linux_amd64.s:560
  12   Thread 0x7ffed67fc700 (LWP 2368463) "nginx"        runtime.futex () at /root/go/src/runtime/sys_linux_amd64.s:560

和有問題時(shí)的info threads信息對比,發(fā)現(xiàn)多了好幾個(gè)runtime.futex的線程,這些線程即是運(yùn)行g(shù)o程序需要的線程。之前的程序之所以沒出問題,是因?yàn)橹暗某绦驔]有調(diào)用fork,所以不會(huì)出現(xiàn)此問題。

額外問題

在有問題的時(shí)候,為什么觸發(fā)GC的時(shí)候?qū)е耮o程序無法運(yùn)行,一直處在死循環(huán)中?這個(gè)需要了解go的垃圾回收機(jī)制才能知道原因,我本身對go不太熟悉,所以只是簡單了解了一點(diǎn),還無法詳細(xì)解釋清楚。

以上就是C語言調(diào)用go生成的動(dòng)態(tài)庫的踩坑過程解析的詳細(xì)內(nèi)容,更多關(guān)于C語言調(diào)用go動(dòng)態(tài)庫的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 你真的理解C語言qsort函數(shù)嗎?帶你深度剖析qsort函數(shù)

    你真的理解C語言qsort函數(shù)嗎?帶你深度剖析qsort函數(shù)

    這篇文章主要介紹了你真的理解C語言qsort函數(shù)嗎?帶你深度剖析qsort函數(shù),本篇將引入一個(gè)庫函數(shù)來實(shí)現(xiàn)我們希望的順序,結(jié)合示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • C++中DeviceIoCteatol的用法實(shí)例

    C++中DeviceIoCteatol的用法實(shí)例

    這篇文章主要介紹了C++中DeviceIoCteatol的用法實(shí)例,對于學(xué)習(xí)C++針對硬件的操作有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2014-10-10
  • C++實(shí)現(xiàn)有向圖鄰接表的構(gòu)建

    C++實(shí)現(xiàn)有向圖鄰接表的構(gòu)建

    這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)有向圖鄰接表的構(gòu)建,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-04-04
  • VS2019中QT連接及使用的方法步驟

    VS2019中QT連接及使用的方法步驟

    這篇文章主要介紹了VS2019中QT連接及使用的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • 淺談c語言中一種典型的排列組合算法

    淺談c語言中一種典型的排列組合算法

    下面小編就為大家?guī)硪黄獪\談c語言中一種典型的排列組合算法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-05-05
  • C++二維數(shù)組中的查找算法示例

    C++二維數(shù)組中的查找算法示例

    這篇文章主要介紹了C++二維數(shù)組中的查找算法,結(jié)合實(shí)例形式分析了C++二維數(shù)組進(jìn)行查找的原理與具體實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2017-05-05
  • C++實(shí)現(xiàn)stack與queue數(shù)據(jù)結(jié)構(gòu)的模擬

    C++實(shí)現(xiàn)stack與queue數(shù)據(jù)結(jié)構(gòu)的模擬

    stack是一種容器適配器,專門用在具有后進(jìn)先出操作的上下文環(huán)境中,其刪除只能從容器的一端進(jìn)行 元素的插入與提取操作;隊(duì)列是一種容器適配器,專門用于在FIFO上下文(先進(jìn)先出)中操作,其中從容器一端插入元素,另一端提取元素
    2023-04-04
  • C語言數(shù)據(jù)結(jié)構(gòu)之算法的時(shí)間復(fù)雜度

    C語言數(shù)據(jù)結(jié)構(gòu)之算法的時(shí)間復(fù)雜度

    這篇文章主要介紹了C語言數(shù)據(jù)結(jié)構(gòu)之算法的時(shí)間復(fù)雜度,文章基于c語言的相關(guān)資料展開詳細(xì)介紹,具有一定的參價(jià)值,需要的小伙伴可以參考一下
    2022-05-05
  • C語言 module_init函數(shù)與initcall案例詳解

    C語言 module_init函數(shù)與initcall案例詳解

    這篇文章主要介紹了C語言 module_init函數(shù)與initcall案例詳解,本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 總結(jié)C/C++面試中可能會(huì)碰到的字符串指針題

    總結(jié)C/C++面試中可能會(huì)碰到的字符串指針題

    C/C++是最能體現(xiàn)程序員能力的語言之一,其功能強(qiáng)大,在IT行業(yè)的各個(gè)方面都有大量的應(yīng)用。下面這篇文章主要介紹了總結(jié)了在C/C++面試中可能會(huì)碰到的字符串指針題,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-01-01

最新評論