找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
广告投放联系QQ68610888
查看: 3596|回复: 7

Golang 程序动态链接的几个尝试,求助

[复制链接]
本帖最后由 LGA1150 于 2019-1-7 19:38 编辑

众所周知,Golang 程序如此大的一个原因是它全是静态链接的。如果能用到动态链接,可以让各个 Golang 程序共用一个标准库,大大减少 RAM 和 ROM 的使用
我尝试用 OpenWrt buildroot 编译带 Golang 支持的 GCC,在解决几个编译错误后终于编译出 gccgo 和 libgo.so 共享标准库
结果用 gccgo 编译 helloworld 时,在链接时找不到几个 setcontext 等符号,查了下才发现 musl libc 没有实现 ucontext……
得,又在 GitHub 上找了个 https://github.com/kaniini/libucontext (暂时没有 MIPS),编译好后在 gccgo 加上参数 -lucontext 终于不报错了,程序大小只有 10kB
把程序和几个共享库传到我的 ARM 上,ldd 好像没有问题
  1. root@OpenWrt:/tmp# ldd hello
  2.         /lib/ld-musl-armhf.so.1 (0xb6f35000)
  3.         libucontext.so.0 => /lib/libucontext.so.0 (0xb6f23000)
  4.         libgo.so.13 => /lib/libgo.so.13 (0xb611f000)
  5.         libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb6104000)
  6.         libc.so => /lib/ld-musl-armhf.so.1 (0xb6f35000)
复制代码
结果运行时报 malloc 和 mmap 错误
  1. fatal error: runtime: cannot reserve arena virtual address space
  2. runtime: panic before malloc heap initialized

  3. runtime stack:
  4. mmap errno 22
  5. fatal error: mmap
  6. runtime: panic before malloc heap initialized
  7. panic during panic

  8. runtime stack:
  9. mmap errno 22
  10. fatal error: mmap
  11. runtime: panic before malloc heap initialized
  12. stack trace unavailable
复制代码
可用 RAM 还有 400多M,应该不是内存不足的问题
有大神知道怎么解决吗?@hackpascal @lintel @ptpt52 @lean
2L 放 strace

请千万不要发布任何涉及时事政治以及涉政涉爆涉恐类的内容,切记!切记!切记! 我的恩山、我的无线 The best wifi forum is right here.
 楼主| | 显示全部楼层
  1. execve("./hello", ["./hello"], 0xbeb9ade0 /* 13 vars */) = 0
  2. set_tls(0xb6fd1590)                     = 0
  3. set_tid_address(0xb6fd1534)             = 19586
  4. open("/etc/ld-musl-armhf.path", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = -1 ENOENT (No such file or directory)
  5. open("/lib/libucontext.so.0", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
  6. fcntl64(3, F_SETFD, FD_CLOEXEC)         = 0
  7. fstat64(3, {st_mode=S_IFREG|0644, st_size=4147, ...}) = 0
  8. read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0\30\4\0\0004\0\0\0"..., 936) = 936
  9. mmap2(NULL, 73728, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xb6f49000
  10. mmap2(0xb6f59000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0) = 0xb6f59000
  11. close(3)                                = 0
  12. open("/lib/libgo.so.13", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
  13. fcntl64(3, F_SETFD, FD_CLOEXEC)         = 0
  14. fstat64(3, {st_mode=S_IFREG|0755, st_size=14516773, ...}) = 0
  15. read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0P\34V\0004\0\0\0"..., 936) = 936
  16. mmap2(NULL, 14696448, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xb6145000
  17. mmap2(0xb6c82000, 2912256, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0xb2d000) = 0xb6c82000
  18. mmap2(0xb6f2e000, 110592, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb6f2e000
  19. close(3)                                = 0
  20. open("/lib/libgcc_s.so.1", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
  21. fcntl64(3, F_SETFD, FD_CLOEXEC)         = 0
  22. fstat64(3, {st_mode=S_IFREG|0644, st_size=41251, ...}) = 0
  23. read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0(\0\1\0\0\0000E\0\0004\0\0\0"..., 936) = 936
  24. mmap2(NULL, 110592, PROT_READ|PROT_EXEC, MAP_PRIVATE, 3, 0) = 0xb612a000
  25. mmap2(0xb6143000, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED, 3, 0x9000) = 0xb6143000
  26. close(3)                                = 0
  27. mprotect(0xb6f59000, 4096, PROT_READ)   = 0
  28. mprotect(0xb6c82000, 1699840, PROT_READ) = 0
  29. mprotect(0xb6143000, 4096, PROT_READ)   = 0
  30. mprotect(0x21000, 4096, PROT_READ)      = 0
  31. sched_getaffinity(0, 128, [0, 1])       = 4
  32. brk(NULL)                               = 0x1427000
  33. write(2, "fatal error: ", 13fatal error: )           = 13
  34. write(2, "runtime: cannot reserve arena vi"..., 51runtime: cannot reserve arena virtual address space) = 51
  35. write(2, "\n", 1
  36. )                       = 1
  37. write(2, "runtime: panic before malloc hea"..., 46runtime: panic before malloc heap initialized
  38. ) = 46
  39. _newselect(0, NULL, NULL, NULL, {tv_sec=0, tv_usec=1000}) = 0 (Timeout)
  40. _newselect(0, NULL, NULL, NULL, {tv_sec=0, tv_usec=1000}) = 0 (Timeout)
  41. write(2, "\nruntime stack:\n", 16
  42. runtime stack:
  43. )      = 16
  44. stat64(NULL, 0xbe8b4200)                = -1 EFAULT (Bad address)
  45. mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb6fce000
  46. mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb6fcd000
  47. open("/proc/self/exe", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
  48. fcntl64(3, F_SETFD, FD_CLOEXEC)         = 0
  49. fcntl64(3, F_SETFD, FD_CLOEXEC)         = 0
  50. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb6fcc000
  51. munmap(0xb6fcc000, 4096)                = 0
  52. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 3, 0x2000) = 0xb6fcc000
  53. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 3, 0x2000) = 0xb6fcb000
  54. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb6fca000
  55. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb6fc9000
  56. munmap(0xb6fca000, 4096)                = 0
  57. munmap(0xb6fcc000, 4096)                = 0
  58. munmap(0xb6fcb000, 4096)                = 0
  59. close(3)                                = 0
  60. open("./hello", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
  61. fcntl64(3, F_SETFD, FD_CLOEXEC)         = 0
  62. fcntl64(3, F_SETFD, FD_CLOEXEC)         = 0
  63. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb6fcc000
  64. munmap(0xb6fcc000, 4096)                = 0
  65. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 3, 0x2000) = 0xb6fcc000
  66. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 3, 0x2000) = 0xb6fcb000
  67. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb6fca000
  68. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb6fc8000
  69. munmap(0xb6fca000, 4096)                = 0
  70. munmap(0xb6fcc000, 4096)                = 0
  71. munmap(0xb6fcb000, 4096)                = 0
  72. close(3)                                = 0
  73. open("/lib/libucontext.so.0", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
  74. fcntl64(3, F_SETFD, FD_CLOEXEC)         = 0
  75. fcntl64(3, F_SETFD, FD_CLOEXEC)         = 0
  76. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb6fcc000
  77. munmap(0xb6fcc000, 4096)                = 0
  78. mmap2(NULL, 0, PROT_READ, MAP_PRIVATE, 3, 0) = -1 EINVAL (Invalid argument)
  79. write(2, "mmap", 4mmap)                     = 4
  80. write(2, " errno ", 7 errno )                  = 7
  81. write(2, "22", 222)                       = 2
  82. write(2, "\n", 1
  83. )                       = 1
  84. write(2, "fatal error: ", 13fatal error: )           = 13
  85. write(2, "mmap", 4mmap)                     = 4
  86. write(2, "\n", 1
  87. )                       = 1
  88. write(2, "runtime: panic before malloc hea"..., 46runtime: panic before malloc heap initialized
  89. ) = 46
  90. write(2, "panic during panic\n", 19panic during panic
  91. )    = 19
  92. write(2, "\nruntime stack:\n", 16
  93. runtime stack:
  94. )      = 16
  95. mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb6fcc000
  96. open("/proc/self/exe", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 4
  97. fcntl64(4, F_SETFD, FD_CLOEXEC)         = 0
  98. fcntl64(4, F_SETFD, FD_CLOEXEC)         = 0
  99. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 4, 0) = 0xb6fcb000
  100. munmap(0xb6fcb000, 4096)                = 0
  101. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 4, 0x2000) = 0xb6fcb000
  102. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 4, 0x2000) = 0xb6fca000
  103. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 4, 0) = 0xb6fc7000
  104. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 4, 0) = 0xb6fc6000
  105. munmap(0xb6fc7000, 4096)                = 0
  106. munmap(0xb6fcb000, 4096)                = 0
  107. munmap(0xb6fca000, 4096)                = 0
  108. close(4)                                = 0
  109. open("./hello", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 4
  110. fcntl64(4, F_SETFD, FD_CLOEXEC)         = 0
  111. fcntl64(4, F_SETFD, FD_CLOEXEC)         = 0
  112. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 4, 0) = 0xb6fcb000
  113. munmap(0xb6fcb000, 4096)                = 0
  114. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 4, 0x2000) = 0xb6fcb000
  115. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 4, 0x2000) = 0xb6fca000
  116. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 4, 0) = 0xb6fc7000
  117. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 4, 0) = 0xb6fc5000
  118. munmap(0xb6fc7000, 4096)                = 0
  119. munmap(0xb6fcb000, 4096)                = 0
  120. munmap(0xb6fca000, 4096)                = 0
  121. close(4)                                = 0
  122. open("/lib/libucontext.so.0", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 4
  123. fcntl64(4, F_SETFD, FD_CLOEXEC)         = 0
  124. fcntl64(4, F_SETFD, FD_CLOEXEC)         = 0
  125. mmap2(NULL, 4096, PROT_READ, MAP_PRIVATE, 4, 0) = 0xb6fcb000
  126. munmap(0xb6fcb000, 4096)                = 0
  127. mmap2(NULL, 0, PROT_READ, MAP_PRIVATE, 4, 0) = -1 EINVAL (Invalid argument)
  128. write(2, "mmap", 4mmap)                     = 4
  129. write(2, " errno ", 7 errno )                  = 7
  130. write(2, "22", 222)                       = 2
  131. write(2, "\n", 1
  132. )                       = 1
  133. write(2, "fatal error: ", 13fatal error: )           = 13
  134. write(2, "mmap", 4mmap)                     = 4
  135. write(2, "\n", 1
  136. )                       = 1
  137. write(2, "runtime: panic before malloc hea"..., 46runtime: panic before malloc heap initialized
  138. ) = 46
  139. write(2, "stack trace unavailable\n", 24stack trace unavailable
  140. ) = 24
  141. exit_group(4)                           = ?
  142. +++ exited with 4 +++
复制代码
请千万不要发布任何涉及时事政治以及涉政涉爆涉恐类的内容,切记!切记!切记! 我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

来自手机 | 显示全部楼层
大佬全是专业课题
请千万不要发布任何涉及时事政治以及涉政涉爆涉恐类的内容,切记!切记!切记! 我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

不了解go
不过openwrt也可以用glibc,可否尝试一下
请千万不要发布任何涉及时事政治以及涉政涉爆涉恐类的内容,切记!切记!切记! 我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

 楼主| | 显示全部楼层
ptpt52 发表于 2019-1-7 18:38
不了解go
不过openwrt也可以用glibc,可否尝试一下

单单为了 ucontext 用 glibc 是不是有点小题大做了,而且 glibc 又比 musl 和 uClibc 大
请千万不要发布任何涉及时事政治以及涉政涉爆涉恐类的内容,切记!切记!切记! 我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

我猜还是那个libucontext有问题
看strace里面每次打开共享库在mmap2()之前都有调用fstat()和read(),但是打开libucontext就没有
请千万不要发布任何涉及时事政治以及涉政涉爆涉恐类的内容,切记!切记!切记! 我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

 楼主| 来自手机 | 显示全部楼层
wjrsonic 发表于 2019-1-7 21:04
我猜还是那个libucontext有问题
看strace里面每次打开共享库在mmap2()之前都有调用fstat()和read(),但是 ...

那个库我用另外一个 C 程序测过,没有问题
请千万不要发布任何涉及时事政治以及涉政涉爆涉恐类的内容,切记!切记!切记! 我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

LGA1150 发表于 2019-1-8 14:54
那个库我用另外一个 C 程序测过,没有问题

还是gdb跟一下看看库的初始化出了什么问题吧
实在搞不定的话还有一个备选方案可以试试,让glibc和musl共存,运行golang程序时用LD_LIBRARY_PATH指定库的路径
请千万不要发布任何涉及时事政治以及涉政涉爆涉恐类的内容,切记!切记!切记! 我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

欢迎大家光临恩山无线论坛上一条 /1 下一条

有疑问请添加管理员QQ86788181|手机版|小黑屋|Archiver|恩山无线论坛(常州市恩山计算机开发有限公司版权所有) ( 苏ICP备05084872号 )

GMT+8, 2024-5-7 11:10

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

| 江苏省互联网有害信息举报中心 举报信箱:js12377 | @jischina.com.cn 举报电话:025-88802724 本站不良内容举报信箱:68610888@qq.com 举报电话:0519-86695797

快速回复 返回顶部 返回列表