Linux多线程,静态编译程序可执行,动态编译程序报Segmentation fault

曾经的洒脱 2013-08-03 06:06:18
使用的交叉编译arm-linux-gcc pthread.c -o a.out -lpthread -static

pthread.c源代码:

#include <stdio.h>
#include <pthread.h>
#include <unistd.h>


void *threadfuc(void *pvoid)
{
int id = (int)pvoid;
printf("Child thread %d says:Hello world!\n", id);

return NULL;
}

int main()
{
pthread_t tid1,tid2;
pthread_create(&tid1, NULL, &threadfuc, (void *)1);
pthread_create(&tid2, NULL, &threadfuc, (void *)2);

pthread_detach(tid1);

/* 第二个参数:等待线程的返回值 */
pthread_join(tid2, NULL);
printf("Main thread say:Hello world!\n");
return 0;
}


问题是:
编译没错误,静态编译的程序可在开发板上执行,动态编译的程序运行时直接报Segmentation fault,似乎这个程序一点都不会执行。
u-boot、内核及文件系统都是自己移植的,在开发板上的/lib目录中与pthread相关的库文件有:

自己已经找不出是什么原因了,求大神指教!!!感激不尽。。。。
...全文
347 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
曾经的洒脱 2013-08-06
  • 打赏
  • 举报
回复
引用 13 楼 ali88z 的回复:
libpthread.so不应该也是个链接,链接到0.10.so吗?
嗯是的,我试过使用你说的哪个连接文件,可是还是不行。 不过今天已经把问题给解决了,我重新烧写了下文件系统,这个问题就奇怪的消失了,呵呵 不过还是很谢谢大家的帮忙!
dongjiawei316 2013-08-06
  • 打赏
  • 举报
回复
你不传线程的参数1和2,试试看?
ali88z 2013-08-06
  • 打赏
  • 举报
回复
libpthread.so不应该也是个链接,链接到0.10.so吗?
曾经的洒脱 2013-08-05
  • 打赏
  • 举报
回复
引用 11 楼 city_of_the_sky 的回复:
你的这些库是不是从交叉编译环境中拷贝的?
嗯,是的,不会错的,应该我昨天又重新拷贝了一遍,我特别注意了这个问题,我猜的也是动态链接库的原因,但是我开发板下的/lib目录中与pthread相关的文件全是交叉编译链工具中复制过来的,而且加了 -d选项,保留符号链接。
XiaoCk_Linux 2013-08-05
  • 打赏
  • 举报
回复
你的这些库是不是从交叉编译环境中拷贝的?
XiaoCk_Linux 2013-08-05
  • 打赏
  • 举报
回复
动态编译后文件是需要依赖你的开发板系统的,如果开发板上的系统没有相应的线程库,会报错!当然这只是我的猜测,我只是提供一种思路。 PS(动态链接就是要动态的链接,运行时候动态的链接dll)
XiaoCk_Linux 2013-08-05
  • 打赏
  • 举报
回复
建议去看看动态编译和静态编译的区别,毕竟静态编译没问题。
u011584371 2013-08-04
  • 打赏
  • 举报
回复
(void*)1 这样写好吗 相当于去取内存地址为1的数据
沭水河畔 2013-08-04
  • 打赏
  • 举报
回复
我遇到过这样的情况,kernel+rootfs是低版本的mips gcc编译的,app是高版本的mips gcc编译的,动态链接的话app运行就抛SEGV,静态链接的话正常运行。 通常rootfs里的lib是从编译器目录里提取的,猜测不同版本编译器的库二进制代码有所不同。
曾经的洒脱 2013-08-04
  • 打赏
  • 举报
回复
引用 7 楼 u011584371 的回复:
[quote=引用 5 楼 cjkl111 的回复:] [quote=引用 4 楼 u011584371 的回复:] (void*)1 这样写好吗 相当于去取内存地址为1的数据
我只是把1转化为地址,但是并没有去这个地址取值啊!而且进入threadfuc函数,我马上就把他给转为整型了,而且Linux还有VFS层,这个(void*)1也并不是指物理地址1啊![/quote] 1和void*所占字符数可能不同 指针和普通数据类型之间还是不要互转吧[/quote] 呵呵 如果不转也可以,但是还是强制转换了,出现警告
u011584371 2013-08-04
  • 打赏
  • 举报
回复
引用 5 楼 cjkl111 的回复:
[quote=引用 4 楼 u011584371 的回复:] (void*)1 这样写好吗 相当于去取内存地址为1的数据
我只是把1转化为地址,但是并没有去这个地址取值啊!而且进入threadfuc函数,我马上就把他给转为整型了,而且Linux还有VFS层,这个(void*)1也并不是指物理地址1啊![/quote] 1和void*所占字符数可能不同 指针和普通数据类型之间还是不要互转吧
曾经的洒脱 2013-08-04
  • 打赏
  • 举报
回复
引用 3 楼 lishanchao 的回复:
我遇到过这样的情况,kernel+rootfs是低版本的mips gcc编译的,app是高版本的mips gcc编译的,动态链接的话app运行就抛SEGV,静态链接的话正常运行。 通常rootfs里的lib是从编译器目录里提取的,猜测不同版本编译器的库二进制代码有所不同。
哦,这样啊,我记得编译内核与文件系统所使用的arm-linux-gcc版本好像不一样,不太记得了,如果真如你说的那样,能有什么好的工具解决这个问题吗?
曾经的洒脱 2013-08-04
  • 打赏
  • 举报
回复
引用 4 楼 u011584371 的回复:
(void*)1 这样写好吗 相当于去取内存地址为1的数据
我只是把1转化为地址,但是并没有去这个地址取值啊!而且进入threadfuc函数,我马上就把他给转为整型了,而且Linux还有VFS层,这个(void*)1也并不是指物理地址1啊!
曾经的洒脱 2013-08-03
  • 打赏
  • 举报
回复
引用 1 楼 qq120848369 的回复:
那的确是你移植的问题了。
是哪个地方?文件系统还是内核?
qq120848369 2013-08-03
  • 打赏
  • 举报
回复
那的确是你移植的问题了。

23,120

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧