LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1440|回复: 10

非常疑难问题求解. 是不是OS的问题?

[复制链接]
发表于 2006-7-12 17:43:10 | 显示全部楼层 |阅读模式
项目中出现了Segfault问题,实在搞不清楚为什么会这样,向各位求解。
不知是否遇到过类似情况。

问题:
1) 是不是系统的兼容性存在问题。
2)  有什么解决办法么?

编译环境: RHEL AS3 EM64T
运行环境: RHEL AS4 EM64T (kernel 2.6.34)

将程序结构简化,并写了一个测试小程序。

测试小程序说明:
  1) loadlib.dll中封装了两个函数,分别调用了dlopen和dlclose。
 2) main.c中利用loadlib.dll里的函数加载lib1.so和lib2.so
 3) lib1.so中动态加载了系统的库libm.so

  调用关系如下:
  test(loadlib.dll) (gcc编译)
    |- lib1.so     (g++编译)
    |   `- libm.so  (系统的库)
     `- lib2.so (g++编译)

再现方法:
 1)RHEL3(EM64T)中将附件的tgz解压缩
   tar xvzf test.tgz
      包含如下目录:
    test/main
      test/lib12

  2)按如下方法做成lib1.so和lib2.so,并拷贝至test/main下
  #cd test/lib12
      #make
      #cp lib1.so lib2.so ../main

  3)按照如下方法做成loadlib.dll和test。
  #cd test/main
      #make

  注:做成test时使用了-lefence链接了ElectricFence内存检查库。  

 4)将以上的各个文件拷贝至RHEL4(EM64T)环境、执行test/main下的test则会
    导致segfault。   

  但是在RHEL3(EM64T)上执行则没有问题。

 ※RHEL4(EM64T)环境中通过步骤3)再生成loadlib.dll和test时仍然会segfault。
 ※RHEL4(EM64T)环境中只要重新编译了lib1.so和lib2.so之一都不会再产生segfault。

※segfault的backtrace信息如下:
Program received signal SIGSEGV, Segmentation fault.
0x00000039a4e073b9 in do_lookup_x () from /lib64/ld-linux-x86-64.so.2
(gdb) backtrace
#0  0x00000039a4e073b9 in do_lookup_x () from /lib64/ld-linux-x86-64.so.2
#1  0x00000039a4e0784e in _dl_lookup_symbol_x () from /lib64/ld-linux-x86-64.so.2
#2  0x00000039a4e0a63a in fixup () from /lib64/ld-linux-x86-64.so.2
#3  0x00000039a4e0a502 in _dl_runtime_resolve () from /lib64/ld-linux-x86-64.so.2
#4  0x0000002a95a0b8d0 in std::ctype_byname<wchar_t>::ctype_byname ()
   from /usr/lib64/libstdc++.so.5
#5  0x00000039a5230f4b in __cxa_finalize () from /lib64/tls/libc.so.6
#6  0x0000002a95a07877 in ?? () from /usr/lib64/libstdc++.so.5
#7  0x0000007fbffff430 in ?? ()
#8  0x0000002a95a5d701 in ?? () from /usr/lib64/libstdc++.so.5
#9  0x0000007fbffff3b0 in ?? ()
#10 0x00000039a52f85d7 in _dl_close () from /lib64/tls/libc.so.6
Previous frame inner to this frame (corrupt stack?)

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
 楼主| 发表于 2006-7-17 14:01:45 | 显示全部楼层
自己顶一下。

各位大侠,又没有遇到过类似的RHEL3 和RHEL4不兼容的地方?
回复 支持 反对

使用道具 举报

发表于 2006-7-17 22:39:01 | 显示全部楼层
问题出在你调用了两次dlclose()...
在lib1.c中和在loadlib的freelib()中,调用了两个dlclose(),我把lib1.c中的去掉就没有错误了。

附件为改后的test。做一下diff就知道了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-7-18 11:03:00 | 显示全部楼层
多谢回复,终于见到回贴了。感动

您是说在lib1.c中libm的被调用了两次dlclose()么?

按照程序流程来说应该不会被调用两次,因为lib1.c(lib1.so)中的DllEntryPoint
被调用了两次,第一次为dlopen,第二次为dlclose.

而且如果是两次free时segfault的backtrace信息和一楼贴出来的也不一样。

其他信息:
假如我把loadlib()的freelib()两个函数放在main.c里,而不是做成loadlib.dll的话
也不会有问题。
回复 支持 反对

使用道具 举报

发表于 2006-7-18 21:05:47 | 显示全部楼层
不过,loadlib.c中的freelib()里也调用了一次dlclose(),
在lib1.c中又调用了一次dlclose();
这样同一个handle不是被释放了两次吗?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-7-19 09:03:25 | 显示全部楼层
Post by linuxahah
不过,loadlib.c中的freelib()里也调用了一次dlclose(),
在lib1.c中又调用了一次dlclose();
这样同一个handle不是被释放了两次吗?


不是同一个handle。
1)     lib1.c中调用的dlclose()释放的是 libm.so 的handle
2) freelib()里调用的dlclose()释放的是 lib1.so 或 lib2.so 的handle
回复 支持 反对

使用道具 举报

发表于 2006-7-21 10:45:58 | 显示全部楼层
那就不知道了,没仔细看,不过去掉在我这里是好用了。
话又说回来了,不free掉也无所谓吧我想。吼吼。。只要不是无限malloc()就不会有问题的。 新版linux下,有一点点问题就‘段错误’。你用 valgrind、gdb等工具跟一下吧。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-7-21 10:57:36 | 显示全部楼层
这个问题暂时已经提交给OS组调查了。

非常感谢您的回答。
回复 支持 反对

使用道具 举报

发表于 2006-7-21 11:26:58 | 显示全部楼层
在freelib()中,有两句在一起的语句,func(handle,0,0)和dlclose(handle)是吧。一个调用lib1.so中的那个东东释放libm指针。另一个释放lib1.so本身。
我的问题是:lib1.so中的指针libm在那个func()中被释放了,下面在dlclose(handle)释放lib1.so本身的语句中,libm指针会不会重新被释放一次呢?
回复 支持 反对

使用道具 举报

发表于 2008-6-5 10:51:33 | 显示全部楼层
为了看这个帖子才注册的,呵

我最近有遇到类似的问题,我怀疑是两次dlopen导致的问题

有人帮忙讲解一下么?
回复 支持 反对

使用道具 举报

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

本版积分规则

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