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

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

#include 
#include 
#include 

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 

       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.


你可能感兴趣的:(S1:,C/C++,s2:,软件进阶,s2:,Linux编程,s2:,Linux杂项,s2:,进程线程,s2:,嵌入式,s2:,后台开发,s2:,活捉Bug)