我有两个相同行为的实现,我认为它们应该产生相同的结果,但却产生了不同的结果。在 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: 0x7f2645b1b690
package 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: 0x7f2645b1b690
package main
另一点是,如果我查找符号而malloc不是accept.
慕侠2389804
小怪兽爱吃肉
相关分类