thread specific data产生的stack smashing

hifrog 2007-09-28 11:35:28
大家好,今天学习编程遇到了一个问题,下面的一个程序使用了thread specific data,目的是为每一个线程保存一个日志文件的FILE流。源码如下:

#include <stdlib.h>
#include <pthread.h>
#include <stdio.h>
static pthread_key_t thread_log_key;

void write_to_thread_log(const char* message)
{
FILE* thread_log=(FILE*)pthread_getspecific(thread_log_key);
fprintf(thread_log,"%s\n",message);
printf("thread_log_key=%x\tthreadID=%x\tthread_log=%x\n",thread_log_key,pthread_self(),thread_log);
}
void close_thread_log(void* thread_log)
{
fclose((FILE*)thread_log);
}
void* thread_function(void* args)
{
char thread_log_filename[20];
FILE* thread_log;
sprintf(thread_log_filename,"thread%d.log",(int)pthread_self());
thread_log=fopen(thread_log_filename,"w");
pthread_setspecific(thread_log_key,thread_log);
write_to_thread_log("Thread starting.");
sleep(1);
return NULL;
}

int main()
{
int i;
pthread_t threads[5];
pthread_key_create(&thread_log_key,close_thread_log);
for(i=0;i<5;++i)
pthread_create(&(threads[i]),NULL,thread_function,NULL);
for(i=0;i<5;++i)
pthread_join(threads[i],NULL);
return 0;
}

运行时显示:

# ./tsd
thread_log_key=0 threadID=b7e43b90 thread_log=804a2d8
thread_log_key=0 threadID=b7642b90 thread_log=804a440
thread_log_key=0 threadID=b6e41b90 thread_log=804a5a8
thread_log_key=0 threadID=b6640b90 thread_log=804a710
thread_log_key=0 threadID=b5e3fb90 thread_log=804a878
*** stack smashing detected ***: ./tsd terminated
Aborted (core dumped)

以下是用gdb调试的信息:

# gdb tsd
GNU gdb 6.6-debian
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...
Using host libthread_db library "/lib/tls/i686/cmov/libthread_db.so.1".
(gdb) run
Starting program: /home/zx/lp_study/c4s3/tsd
[Thread debugging using libthread_db enabled]
[New Thread -1209739584 (LWP 8271)]
[New Thread -1209742448 (LWP 8274)]
thread_log_key=0 threadID=b7e4cb90 thread_log=804a128
[New Thread -1218135152 (LWP 8275)]
thread_log_key=0 threadID=b764bb90 thread_log=804a320
[New Thread -1226527856 (LWP 8276)]
thread_log_key=0 threadID=b6e4ab90 thread_log=804a518
[New Thread -1234920560 (LWP 8277)]
thread_log_key=0 threadID=b6649b90 thread_log=804a710
[New Thread -1243313264 (LWP 8278)]
thread_log_key=0 threadID=b5e48b90 thread_log=804a878
*** stack smashing detected ***: /home/zx/lp_study/c4s3/tsd terminated

Program received signal SIGABRT, Aborted.
[Switching to Thread -1209742448 (LWP 8274)]
0xffffe410 in __kernel_vsyscall ()
(gdb) where
#0 0xffffe410 in __kernel_vsyscall ()
#1 0xb7e78df0 in raise () from /lib/tls/i686/cmov/libc.so.6
#2 0xb7e7a641 in abort () from /lib/tls/i686/cmov/libc.so.6
#3 0xb7eae9bb in ?? () from /lib/tls/i686/cmov/libc.so.6
#4 0x00000036 in ?? ()
#5 0x0804899c in ?? ()
#6 0x0804897f in ?? ()
#7 0xb7f768d8 in ?? () from /lib/tls/i686/cmov/libc.so.6
#8 0x00000021 in ?? ()
#9 0xbfdd88ad in ?? ()
#10 0x0000001a in ?? ()
#11 0xb7f768fb in ?? () from /lib/tls/i686/cmov/libc.so.6
#12 0x0000000c in ?? ()
#13 0x00000010 in ?? ()
#14 0x00000004 in ?? ()
#15 0x00000000 in ?? ()
(gdb)

我相信这是程序的问题,不会是libpthread的bug,请问如何在程序中解决这个栈溢出的问题呢?谢谢!
...全文
222 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
hefuhua 2007-09-29
  • 打赏
  • 举报
回复
末好意思了,谢谢先:)
hifrog 2007-09-29
  • 打赏
  • 举报
回复
是32位的
tid=b7e4cb90大约为10的11次方,“thread-”的长度为7,“.log”的长度为4,10+7+4+1=22正好超过了20。
cceczjxy 2007-09-29
  • 打赏
  • 举报
回复
楼主的系统不会是64位的吧,
hefuhua 2007-09-29
  • 打赏
  • 举报
回复
"原来是tid太长了"
跟gcc版本有关系?还是生成太长后,如生成都20位,那么有效位为5,这样你前面5位有效位只有有个相同就冲突?
hefuhua 2007-09-29
  • 打赏
  • 举报
回复
兄弟,偶尔睡不着,就再起来逛逛

上班时间很早,没有办法...
cceczjxy 2007-09-29
  • 打赏
  • 举报
回复
老兵大哥,你晚上不用休息吗?
怎么晚还在,早上又来这么早,真是强人.
hifrog 2007-09-29
  • 打赏
  • 举报
回复
问题解决了,原来是tid太长了,生成的文件名字符串长度超过了20。把thread_log_filename的长度改成50就ok了:)
欢迎继续讨论,散分!明天起床就结贴。
hefuhua 2007-09-29
  • 打赏
  • 举报
回复
if(!thread_log)改if(thread_log)
hefuhua 2007-09-29
  • 打赏
  • 举报
回复
我的电脑调试没有出现这个问题

建议修改
void* thread_function(void* args)
{
FILE* thread_log=NULL;
..
}
void close_thread_log(void* thread_log)
{
if(!thread_log){
fsync(thread_log);
fclose((FILE*)thread_log);
}
}

或者先把fclose((FILE*)thread_log);先移到thread_function函数里试试

23,121

社区成员

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

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