亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么 dlsym 在 cgo 中產生的結果與在 c 中產生的結果不同?

為什么 dlsym 在 cgo 中產生的結果與在 c 中產生的結果不同?

Go
拉風的咖菲貓 2023-06-05 13:23:51
我有兩個相同行為的實現,我認為它們應該產生相同的結果,但卻產生了不同的結果。在 Go 中使用 編譯時cgo,我得到的符號地址解析與在 C 中編譯時不同。我想了解原因。我將問題簡化為幾個小例子,一個用 C 語言,一個用 Go 語言。我在我的 Mac 筆記本電腦上運行的 Ubuntu 18 Docker 容器中測試了這些。測試.c:// gcc test.c -D_GNU_SOURCE -ldl// Output: Real: 0x7fd05559d7d0 Current: 0x7fd05559d7d0#include <dlfcn.h>#include <stdio.h>int main() {    void * fd = dlopen("libc.so.6", RTLD_LAZY);    void * real_sym = dlsym(fd, "accept");    void * curr_sym = dlsym(RTLD_NEXT, "accept");    printf("Real: %p Current: %p\n", real_sym, curr_sym);    return 0;}測試去:// go build test.go// Output: Real: 0x7f264583b7d0 Current: 0x7f2645b1b690package main// #cgo CFLAGS: -D_GNU_SOURCE// #cgo LDFLAGS: -ldl// #include <dlfcn.h>import "C"import "fmt"func main() {    fp := C.dlopen(C.CString("libc.so.6"), C.RTLD_LAZY)    real_sym := C.dlsym(fp, C.CString("accept"))    curr_sym := C.dlsym(C.RTLD_NEXT, C.CString("accept"))    fmt.Printf("Real: %p Current: %p\n", real_sym, curr_sym)}Real: 0x7fd05559d7d0 Current: 0x7fd05559d7d0我得到了when test.cgets compiled ( )的輸出gcc test.c -D_GNU_SOURCE -ldl。但是,當我構建時,test.go我看到了Real: 0x7f264583b7d0 Current: 0x7f2645b1b690.我假設 go 本身正在包裝一些符號,但我想知道到底發生了什么。謝謝!看到一些最初的評論后,再補充幾件。我更改test.c如下,然后循環運行(while [ 1 ]; do   ./a.out; done)。它一直為我獲得相同的地址(雖然每次運行都不同)。// gcc test.c -D_GNU_SOURCE -ldl// Output: Real: 0x7fd05559d7d0 Current: 0x7fd05559d7d0#include <dlfcn.h>#include <stdio.h>    int main() {    void * fd = dlopen("libc.so.6", RTLD_LAZY);    void * real_sym = dlsym(fd, "accept");    void * curr_sym = dlsym(RTLD_NEXT, "accept");    if(real_sym != curr_sym) {        printf("Real: %p Current: %p\n", real_sym, curr_sym);    }    return 0;}我還嘗試修改 Go 代碼以檢查它是否與 Go 調用 C 的方式有關,但地址仍然不匹配:// go build dos.go// Output: Real: 0x7f264583b7d0 Current: 0x7f2645b1b690package main另一點是,如果我查找符號而malloc不是accept.
查看完整描述

2 回答

?
慕俠2389804

TA貢獻1719條經驗 獲得超6個贊

原因是 Go 鏈接到 libpthread,但你的 C 程序沒有。如果我添加-lpthread到 gcc 參數,它也會打印不同的指針。因此,libpthread 定義了它自己的accept并覆蓋了 libc 的(這是有道理的)。

我想出來的方法是,我在兩個程序中都插入了一個睡眠,然后翻查/proc/$pid/maps以查看返回的指針引用的內容。這表明在 Go 的例子中,“當前”指針駐留在 libpthread 中?!罢嬲摹敝羔樋偸且?libc。


查看完整回答
反對 回復 2023-06-05
?
小怪獸愛吃肉

TA貢獻1852條經驗 獲得超1個贊

符號不會加載到內存中的固定地址;他們去裝載機決定放置它們的任何地方。


這是我在我的機器上多次運行你的 C 程序的輸出。


govind@Govind-PC:/mnt/c/Temp$ ./dlst

Real: 0x7f4b5f3127d0 Current: 0x7f4b5f26ee30

govind@Govind-PC:/mnt/c/Temp$ ./dlst

Real: 0x7f45727127d0 Current: 0x7f457266ee30

govind@Govind-PC:/mnt/c/Temp$ ./dlst

Real: 0x7fc3373127d0 Current: 0x7fc33726ee30

govind@Govind-PC:/mnt/c/Temp$ ./dlst

Real: 0x7f0e555127d0 Current: 0x7f0e5546ee30

govind@Govind-PC:/mnt/c/Temp$ ./dlst

Real: 0x7f2fdd9127d0 Current: 0x7f2fdd86ee30

govind@Govind-PC:/mnt/c/Temp$ ./dlst

Real: 0x7fec7db127d0 Current: 0x7fec7da6ee30

govind@Govind-PC:/mnt/c/Temp$ ./dlst

Real: 0x7f07de1127d0 Current: 0x7f07de06ee30

govind@Govind-PC:/mnt/c/Temp$

查看完整回答
反對 回復 2023-06-05
  • 2 回答
  • 0 關注
  • 223 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號