线程堆栈过小引起内存溢出, 进而导致core dump

972 篇文章 329 订阅
148 篇文章 34 订阅

       之前在某微线程服务中遇到过一次, 线程堆栈设置过小, 导致程序崩溃(core dump),  通过加大线程堆栈的大小的设置解决了问题。 最近又碰到, 简单来看下:      

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

void* threadFunc(void* p)  
{  
	char szTest[1024 * 32] = {0};   // 32K, core dump here
    return NULL;  
}  
 
int main(void)
{
	size_t ui_stack_size = 0;
	pthread_attr_t attr;
	
	int iRet = pthread_attr_init(&attr);
	if(iRet != 0)
	{
		printf("pthread_attr_init error\n");
		return -1;
	}
	
    iRet = pthread_attr_getstacksize(&attr, &ui_stack_size);
    if(iRet != 0)
	{
		printf("pthread_attr_getstacksize error\n");
		return -1;
	}
	
	printf("ui_stack_size = %uB, %uKB\n", ui_stack_size, ui_stack_size/1024);
	
	ui_stack_size = 20 * 1024;  // 线程堆栈大小设置为20k 
    iRet = pthread_attr_setstacksize(&attr, ui_stack_size);  
    if(iRet != 0)  
    {  
        printf("pthread_attr_getstacksize error\n");  
        return -1;  
    }  
	
	pthread_t id;  
    pthread_create (&id, &attr, threadFunc, NULL);  
	
	getchar();
    return 0;
}

       编译运行并调试(编译g++ -g test.cpp -lpthread):

xxxxxx:~> gdb a.out core.31713
GNU gdb 6.6
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 "i586-suse-linux"...
Using host libthread_db library "/lib/libthread_db.so.1".

warning: Can't read pathname for load map: Input/output error.
Reading symbols from /lib/libonion.so...done.
Loaded symbols for /lib/libonion.so
Reading symbols from /lib/libpthread.so.0...done.
Loaded symbols for /lib/libpthread.so.0
Reading symbols from /usr/lib/libstdc++.so.6...done.
Loaded symbols for /usr/lib/libstdc++.so.6
Reading symbols from /lib/libm.so.6...done.
Loaded symbols for /lib/libm.so.6
Reading symbols from /lib/libgcc_s.so.1...done.
Loaded symbols for /lib/libgcc_s.so.1
Reading symbols from /lib/libc.so.6...done.
Loaded symbols for /lib/libc.so.6
Reading symbols from /lib/libdl.so.2...done.
Loaded symbols for /lib/libdl.so.2
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Core was generated by `./a.out'.
Program terminated with signal 11, Segmentation fault.
#0  0x08048668 in threadFunc (p=0x0) at test.cpp:7
7               char szTest[1024 * 32] = {0};
(gdb) bt
#0  0x08048668 in threadFunc (p=0x0) at test.cpp:7
#1  0xb7f9f1eb in start_thread () from /lib/libpthread.so.0
#2  0xb7e017fe in clone () from /lib/libc.so.6
(gdb) f 0
#0  0x08048668 in threadFunc (p=0x0) at test.cpp:7
7               char szTest[1024 * 32] = {0};
(gdb) i locals
szTest = Cannot access memory at address 0xb7fb1468
(gdb) 

        顺便看到, 线程堆栈的默认设置大小是8192KB(8MB),  也可以用命令来查:

xxxxxx:~> ulimit -s
8192
xxxxxx:~> 

       另外, 要注意, 分配内存的时候,不一定core dump,  使用的时候(产生溢出操作), 才会。

 

      最后来说一点, 当我们用到诸如alloc, init之类的操作时(尤其是不熟悉的接口或者第三方库), 一定要关注是否有必要释放/销毁, 避免造成资源消耗殆尽, 出现性能问题。  上面的程序, 其实还应该用pthread_attr_destroy来销毁attr, 看下:

ubuntu@VM-0-15-ubuntu:~$ man pthread_attr_init
PTHREAD_ATTR_INIT(3)                                Linux Programmer's Manual                               PTHREAD_ATTR_INIT(3)

NAME
       pthread_attr_init, pthread_attr_destroy - initialize and destroy thread attributes object

SYNOPSIS
       #include <pthread.h>

       int pthread_attr_init(pthread_attr_t *attr);
       int pthread_attr_destroy(pthread_attr_t *attr);

       Compile and link with -pthread.

DESCRIPTION
       The  pthread_attr_init() function initializes the thread attributes object pointed to by attr with default attribute valâ€
       ues.  After this call, individual attributes of the object can be set using various related functions (listed  under  SEE
       ALSO), and then the object can be used in one or more pthread_create(3) calls that create threads.

       Calling  pthread_attr_init()  on a thread attributes object that has already been initialized results in undefined behavâ€
       ior.

       When a thread attributes object is no longer required, it should be destroyed using the pthread_attr_destroy()  function.
       Destroying a thread attributes object has no effect on threads that were created using that object.

       Once  a thread attributes object has been destroyed, it can be reinitialized using pthread_attr_init().  Any other use of
       a destroyed thread attributes object has undefined results.

RETURN VALUE
       On success, these functions return 0; on error, they return a nonzero error number.

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值