免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3517 | 回复: 19
打印 上一主题 下一主题

[C] 程序链接碰到的奇怪问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-04-21 20:29 |只看该作者 |倒序浏览
大家好 ,碰到一个奇怪的问题,现把问题描述如下:

把一些代码的源文件编译链接后做成库,分别生成静态库.a和动态库.so

然后写程序去调用库中的函数..编译时生成可执行文件.  

现在却发现,当编译时链接静态库.a时能够正确执行(静态编译)

而动态链接.so时,生成的可执行文件却执行报错,报的错误是经典的 "Segmentation fault"


起初还怀疑是makefile里写的不正确,导致有的.o文件没有连接到.so里.

但仔细检查了makefile里,生成库的两句为:

$(LIBRARY_FILE) : $(OBJECTS)    #生成静态库
        $(AR) crs $(LIBRARY_FILE) $(OBJECTS)

$(SHARED_LIBRARY_FILE) : $(OBJECTS) #生成动态库
        $(CC) -fpic -shared -o $(SHARED_LIBRARY_FILE) $(OBJECTS)

由这两句可以说明生成的静态库和动态库都是由相同的.o文件生成的.
请教有没有人知道发生这种现象的原因? 谢谢

论坛徽章:
0
2 [报告]
发表于 2010-04-21 22:04 |只看该作者
用ldd 检查一下看是否调用了正确的动态库

论坛徽章:
0
3 [报告]
发表于 2010-04-22 10:00 |只看该作者
回复二楼: 已用ldd看过,链接没有问题..

进一步观察,发现更加奇怪了..

编译库后生成静态库 liba1.a , liba2.a , liba3.a
     相应生成动态库  liba2.so, liba2.so, liba3.so

然后,我的主程序 main.c 在编译时要去链接库..

1. 如果main.c采取静态编译的方式,编译时链接静态库 liba1.a , liba2.a , liba3.a,
  则最后生成可执行文件 main 为30多M(静态编译将所有的都弄进来了)...此时可以正确执行程序的所有功能.

2. 如果main.c采取动态编译的方式编译时链接动态库  liba2.so, liba2.so, liba3.so
最后生成的可执行文件为几百k, 然后将这三个库liba2.so, liba2.so, liba3.so用ldconfig设置一下,使得程序运行时能正确加载它们.
但此时生成的可执行文件main却有某些功能运行时出现"段错误", 而另外一些功能又能正确运行.

这难道说明动态库里有一些"符号"不存在,动态加载时不能找到它???

ps:上面说明两个可执行程序大小的差异,是为了请教:
1. 可否在静态编译时将不会用到的函数去掉,不链接进来,减小可执行程序的大小?
2. 这样生成的静态库与动态库,难道其中有些函数是静态库有,而动态库不存在的?(一直觉得相同的 .o文件生成的静动态库里的"符号"应该相同,此时怀疑了.)


请达人指点一下错误? (或还需要我提供哪些信息?)

论坛徽章:
0
4 [报告]
发表于 2010-04-22 10:08 |只看该作者
看lz的库名字,应该是在实验,能不能把代码贴出来,大家研究一下?

论坛徽章:
0
5 [报告]
发表于 2010-04-22 10:34 |只看该作者
跟.o一起连接吧,还可以strip。

论坛徽章:
0
6 [报告]
发表于 2010-04-22 10:49 |只看该作者
你是在什么平台下编译的?linux(RHEL 4.8?RHEL5.4?OPENSUSE 11.2?)?FreeBSD?OpenSolaris?AIX?HP Unix?

你用的是什么编译器?(gcc 3.x?gcc4.x?hp cc?)

生成 $(OBJECTS) 用的是什么参数?试试统一使用 -DPIC -fPIC

论坛徽章:
0
7 [报告]
发表于 2010-04-22 11:06 |只看该作者
1.静态链接本来就只会链接用到的函数,不用到的是不会链接进来的
你的问题我怀疑是代码本身有问题,导致错误;
因为生成的静态库与动态库的代码会有一些区别;
但这些区别应该只在寻址方式上有区别,如动态库必须生成位置无关代码

论坛徽章:
0
8 [报告]
发表于 2010-04-22 13:19 |只看该作者
本帖最后由 changyongID 于 2010-04-22 13:20 编辑

谢谢楼上几位的回复.

to 4#rain_fish: 我上面打出的几个库名是为了描述问题更清楚. 源代码是c++的代码,其代码量非常大.不太好贴.

to 5#prolj: 如果我的主程序跟库生成的.o一起链接,这样就不是静态编译了吧...而且现在的问题是主程序里没有问题,只是改变编译时链接的方法(分别用静态链接和动态链接), 这样就导致了不同的运行结果,这也太奇怪了.
更为奇怪的是,动态链接的情况下,部分功能是正常的,只有某个功能运行时出现"段错误".

to 6#drangon: 我的平台是 linux: fedora 11 , gcc version 4.4.0 20090506 (Red Hat 4.4.0-4) (GCC)
最后生成动态库用的是

$(SHARED_LIBRARY_FILE) : $(OBJECTS) #生成动态库
        $(CC) -fpic -shared -o $(SHARED_LIBRARY_FILE) $(OBJECTS)


to 7#zxrjkl: 因为很奇怪,动态链接时,有的功能可以,某个功能就不行..我跟踪了一下源代码,发现跟到某一个函数里出现段错误.. 比如这里,我跟到一个 get()函数里之后遇到段错误..但此时,令我不解的是,难道静态库跟动态库有这方面的差别?为什么静态库链接后就不出错,而动态库就会有点问题呢?

ps:前面几贴都忘记说明:库文件和主程序的源代码都是c++的.

论坛徽章:
0
9 [报告]
发表于 2010-04-22 13:35 |只看该作者
查看断错误那个功能的代码的所有内存操作,尤其是数组。

论坛徽章:
0
10 [报告]
发表于 2010-04-22 14:52 |只看该作者
谢谢prolj, 其实我也是想查到相应函数..

但是无奈, 对c++不熟, 什么继承, 多态, 弄得我都有点快吐了...

我用kscope查看代码,再往程序里添加一些打印信息, 这样的方法跟了几层函数...现在勉强跟踪到一个get()函数
里..

不知道gdb可否用来调试这类错误???

另外, 请问一下, 跟踪c++源码用什么比较好? 现在用的kscope实际上的机制跟vim + ctags一样..
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP