【发布时间】:2014-07-27 15:23:06
【问题描述】:
这是在 Windows XP 上的 VisualStudio 中使用 C/C++ 开发的多线程应用程序。
用户报告它因错误“堆栈溢出”而崩溃
经过调试,发现当计算机内存非常低时,在其中一个线程中调用srand()导致“堆栈溢出”。令人惊讶的是,在调用srand()的线程函数中没有造成大堆栈(静态数组等)
这是崩溃后堆栈的样子:
MyApplication.exe!_NMSG_WRITE(int rterrnum=16) Line 217 C
MyApplication.exe!_amsg_exit(int rterrnum=16) Line 441 + 0x9 bytes C
MyApplication.exe!_getptd() Line 525 + 0x7 bytes C
MyApplication.exe!_LocaleUpdate::_LocaleUpdate(localeinfo_struct * plocinfo=0x00000000) Line 243 + 0x5 bytes C++
MyApplication.exe!_woutput_s_l(_iobuf * stream=0x57674054, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * argptr=0x5767c1ec) Line 1023 C++
MyApplication.exe!_vswprintf_helper(int (_iobuf *, const wchar_t *, localeinfo_struct *, char *)* woutfn=0x0047d580, unsigned short * string=0x57675158, unsigned int count=4076, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * ap=0x5767c1ec) Line 157 + 0x13 bytes C
MyApplication.exe!_vsnwprintf_s_l(unsigned short * string=0x57675158, unsigned int sizeInWords=4096, unsigned int count=4075, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * ap=0x5767c1ec) Line 324 + 0x21 bytes C
MyApplication.exe!_vsnwprintf_s(unsigned short * string=0x57675158, unsigned int sizeInWords=4096, unsigned int count=4075, const wchar_t * format=0x0049aca0, char * ap=0x5767c1ec) Line 376 + 0x1b bytes C
MyApplication.exe!_VCrtDbgReportW(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, char * arglist=0x5767c1ec) Line 515 + 0x36 bytes C
MyApplication.exe!_CrtDbgReportWV(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, char * arglist=0x5767c1ec) Line 241 + 0x1d bytes C++
MyApplication.exe!_CrtDbgReportW(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, ...) Line 258 + 0x1d bytes C++
MyApplication.exe!_NMSG_WRITE(int rterrnum=16) Line 215 + 0x11 bytes C
MyApplication.exe!_amsg_exit(int rterrnum=16) Line 441 + 0x9 bytes C
MyApplication.exe!_getptd() Line 525 + 0x7 bytes C
MyApplication.exe!_LocaleUpdate::_LocaleUpdate(localeinfo_struct * plocinfo=0x00000000) Line 243 + 0x5 bytes C++
MyApplication.exe!_woutput_s_l(_iobuf * stream=0x5767c974, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * argptr=0x57684b0c) Line 1023 C++
MyApplication.exe!_vswprintf_helper(int (_iobuf *, const wchar_t *, localeinfo_struct *, char *)* woutfn=0x0047d580, unsigned short * string=0x5767da78, unsigned int count=4076, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * ap=0x57684b0c) Line 157 + 0x13 bytes C
MyApplication.exe!_vsnwprintf_s_l(unsigned short * string=0x5767da78, unsigned int sizeInWords=4096, unsigned int count=4075, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * ap=0x57684b0c) Line 324 + 0x21 bytes C
MyApplication.exe!_vsnwprintf_s(unsigned short * string=0x5767da78, unsigned int sizeInWords=4096, unsigned int count=4075, const wchar_t * format=0x0049aca0, char * ap=0x57684b0c) Line 376 + 0x1b bytes C
MyApplication.exe!_VCrtDbgReportW(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, char * arglist=0x57684b0c) Line 515 + 0x36 bytes C
MyApplication.exe!_CrtDbgReportWV(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, char * arglist=0x57684b0c) Line 241 + 0x1d bytes C++
MyApplication.exe!_CrtDbgReportW(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, ...) Line 258 + 0x1d bytes C++
MyApplication.exe!_NMSG_WRITE(int rterrnum=16) Line 215 + 0x11 bytes C
MyApplication.exe!_amsg_exit(int rterrnum=16) Line 441 + 0x9 bytes C
MyApplication.exe!_getptd() Line 525 + 0x7 bytes C
MyApplication.exe!_LocaleUpdate::_LocaleUpdate(localeinfo_struct * plocinfo=0x00000000) Line 243 + 0x5 bytes C++
MyApplication.exe!_woutput_s_l(_iobuf * stream=0x57685294, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * argptr=0x5768d42c) Line 1023 C++
MyApplication.exe!_vswprintf_helper(int (_iobuf *, const wchar_t *, localeinfo_struct *, char *)* woutfn=0x0047d580, unsigned short * string=0x57686398, unsigned int count=4076, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * ap=0x5768d42c) Line 157 + 0x13 bytes C
MyApplication.exe!_vsnwprintf_s_l(unsigned short * string=0x57686398, unsigned int sizeInWords=4096, unsigned int count=4075, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * ap=0x5768d42c) Line 324 + 0x21 bytes C
MyApplication.exe!_vsnwprintf_s(unsigned short * string=0x57686398, unsigned int sizeInWords=4096, unsigned int count=4075, const wchar_t * format=0x0049aca0, char * ap=0x5768d42c) Line 376 + 0x1b bytes C
MyApplication.exe!_VCrtDbgReportW(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, char * arglist=0x5768d42c) Line 515 + 0x36 bytes C
MyApplication.exe!_CrtDbgReportWV(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, char * arglist=0x5768d42c) Line 241 + 0x1d bytes C++
MyApplication.exe!_CrtDbgReportW(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, ...) Line 258 + 0x1d bytes C++
MyApplication.exe!_NMSG_WRITE(int rterrnum=16) Line 215 + 0x11 bytes C
MyApplication.exe!_amsg_exit(int rterrnum=16) Line 441 + 0x9 bytes C
MyApplication.exe!_getptd() Line 525 + 0x7 bytes C
MyApplication.exe!_LocaleUpdate::_LocaleUpdate(localeinfo_struct * plocinfo=0x00000000) Line 243 + 0x5 bytes C++
MyApplication.exe!_woutput_s_l(_iobuf * stream=0x5768dbb4, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * argptr=0x57695d4c) Line 1023 C++
MyApplication.exe!_vswprintf_helper(int (_iobuf *, const wchar_t *, localeinfo_struct *, char *)* woutfn=0x0047d580, unsigned short * string=0x5768ecb8, unsigned int count=4076, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * ap=0x57695d4c) Line 157 + 0x13 bytes C
MyApplication.exe!_vsnwprintf_s_l(unsigned short * string=0x5768ecb8, unsigned int sizeInWords=4096, unsigned int count=4075, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * ap=0x57695d4c) Line 324 + 0x21 bytes C
MyApplication.exe!_vsnwprintf_s(unsigned short * string=0x5768ecb8, unsigned int sizeInWords=4096, unsigned int count=4075, const wchar_t * format=0x0049aca0, char * ap=0x57695d4c) Line 376 + 0x1b bytes C
MyApplication.exe!_VCrtDbgReportW(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, char * arglist=0x57695d4c) Line 515 + 0x36 bytes C
MyApplication.exe!_CrtDbgReportWV(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, char * arglist=0x57695d4c) Line 241 + 0x1d bytes C++
MyApplication.exe!_CrtDbgReportW(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, ...) Line 258 + 0x1d bytes C++
MyApplication.exe!_NMSG_WRITE(int rterrnum=16) Line 215 + 0x11 bytes C
MyApplication.exe!_amsg_exit(int rterrnum=16) Line 441 + 0x9 bytes C
MyApplication.exe!_getptd() Line 525 + 0x7 bytes C
MyApplication.exe!_LocaleUpdate::_LocaleUpdate(localeinfo_struct * plocinfo=0x00000000) Line 243 + 0x5 bytes C++
MyApplication.exe!_woutput_s_l(_iobuf * stream=0x576964d4, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * argptr=0x5769e66c) Line 1023 C++
MyApplication.exe!_vswprintf_helper(int (_iobuf *, const wchar_t *, localeinfo_struct *, char *)* woutfn=0x0047d580, unsigned short * string=0x576975d8, unsigned int count=4076, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * ap=0x5769e66c) Line 157 + 0x13 bytes C
MyApplication.exe!_vsnwprintf_s_l(unsigned short * string=0x576975d8, unsigned int sizeInWords=4096, unsigned int count=4075, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * ap=0x5769e66c) Line 324 + 0x21 bytes C
MyApplication.exe!_vsnwprintf_s(unsigned short * string=0x576975d8, unsigned int sizeInWords=4096, unsigned int count=4075, const wchar_t * format=0x0049aca0, char * ap=0x5769e66c) Line 376 + 0x1b bytes C
MyApplication.exe!_VCrtDbgReportW(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, char * arglist=0x5769e66c) Line 515 + 0x36 bytes C
MyApplication.exe!_CrtDbgReportWV(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, char * arglist=0x5769e66c) Line 241 + 0x1d bytes C++
MyApplication.exe!_CrtDbgReportW(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, ...) Line 258 + 0x1d bytes C++
MyApplication.exe!_NMSG_WRITE(int rterrnum=16) Line 215 + 0x11 bytes C
MyApplication.exe!_amsg_exit(int rterrnum=16) Line 441 + 0x9 bytes C
MyApplication.exe!_getptd() Line 525 + 0x7 bytes C
MyApplication.exe!_LocaleUpdate::_LocaleUpdate(localeinfo_struct * plocinfo=0x00000000) Line 243 + 0x5 bytes C++
MyApplication.exe!_woutput_s_l(_iobuf * stream=0x5769edf4, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * argptr=0x576a6f8c) Line 1023 C++
MyApplication.exe!_vswprintf_helper(int (_iobuf *, const wchar_t *, localeinfo_struct *, char *)* woutfn=0x0047d580, unsigned short * string=0x5769fef8, unsigned int count=4076, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * ap=0x576a6f8c) Line 157 + 0x13 bytes C
MyApplication.exe!_vsnwprintf_s_l(unsigned short * string=0x5769fef8, unsigned int sizeInWords=4096, unsigned int count=4075, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * ap=0x576a6f8c) Line 324 + 0x21 bytes C
MyApplication.exe!_vsnwprintf_s(unsigned short * string=0x5769fef8, unsigned int sizeInWords=4096, unsigned int count=4075, const wchar_t * format=0x0049aca0, char * ap=0x576a6f8c) Line 376 + 0x1b bytes C
MyApplication.exe!_VCrtDbgReportW(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, char * arglist=0x576a6f8c) Line 515 + 0x36 bytes C
MyApplication.exe!_CrtDbgReportWV(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, char * arglist=0x576a6f8c) Line 241 + 0x1d bytes C++
MyApplication.exe!_CrtDbgReportW(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, ...) Line 258 + 0x1d bytes C++
MyApplication.exe!_NMSG_WRITE(int rterrnum=16) Line 215 + 0x11 bytes C
MyApplication.exe!_amsg_exit(int rterrnum=16) Line 441 + 0x9 bytes C
MyApplication.exe!_getptd() Line 525 + 0x7 bytes C
MyApplication.exe!_LocaleUpdate::_LocaleUpdate(localeinfo_struct * plocinfo=0x00000000) Line 243 + 0x5 bytes C++
MyApplication.exe!_woutput_s_l(_iobuf * stream=0x576a7714, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * argptr=0x576af8ac) Line 1023 C++
MyApplication.exe!_vswprintf_helper(int (_iobuf *, const wchar_t *, localeinfo_struct *, char *)* woutfn=0x0047d580, unsigned short * string=0x576a8818, unsigned int count=4076, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * ap=0x576af8ac) Line 157 + 0x13 bytes C
MyApplication.exe!_vsnwprintf_s_l(unsigned short * string=0x576a8818, unsigned int sizeInWords=4096, unsigned int count=4075, const wchar_t * format=0x0049aca0, localeinfo_struct * plocinfo=0x00000000, char * ap=0x576af8ac) Line 324 + 0x21 bytes C
MyApplication.exe!_vsnwprintf_s(unsigned short * string=0x576a8818, unsigned int sizeInWords=4096, unsigned int count=4075, const wchar_t * format=0x0049aca0, char * ap=0x576af8ac) Line 376 + 0x1b bytes C
MyApplication.exe!_VCrtDbgReportW(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, char * arglist=0x576af8ac) Line 515 + 0x36 bytes C
MyApplication.exe!_CrtDbgReportWV(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, char * arglist=0x576af8ac) Line 241 + 0x1d bytes C++
MyApplication.exe!_CrtDbgReportW(int nRptType=1, const wchar_t * szFile=0x00000000, int nLine=0, const wchar_t * szModule=0x00000000, const wchar_t * szFormat=0x0049aca0, ...) Line 258 + 0x1d bytes C++
MyApplication.exe!_NMSG_WRITE(int rterrnum=16) Line 215 + 0x11 bytes C
MyApplication.exe!_amsg_exit(int rterrnum=16) Line 441 + 0x9 bytes C
MyApplication.exe!_getptd() Line 525 + 0x7 bytes C
MyApplication.exe!srand(unsigned int seed=231) Line 37 + 0x5 bytes C
>MyApplication.exe!ThreadFunction() Line 126 + 0xa bytes C++
所以我们可以清楚地看到一个调用块在递归中最终导致“堆栈溢出”
我想知道低内存是否真的会导致堆栈溢出。所以我写了 Trial 代码,它分配内存直到它满了,然后调用一个有大堆栈分配的函数。
但是,程序并没有失败。下面是代码:
void CallFunctionWithBigStack()
{
char stack[10240];
stack[10231] = 123; // Let's use 'stack' array so that optimizer won't discard it while compiling
srand(stack[10231]);
}
void AllocateMem (int ChunkSize)
{
unsigned char* ptr;
unsigned int i=0;
while(1)
{
ptr = (unsigned char*) malloc (ChunkSize);
if (ptr)
printf ("\nAllocating %d bytes", ChunkSize);
else
{
printf ("\nERROR allocating memory");
break;
}
i++;
}
}
int _tmain(int argc, _TCHAR* argv[])
{
// Allocate memory till it gets full
AllocateMem (1024*1024*10); // Allocate in 10 of Megabytes
AllocateMem (1024*1024); // Allocate in Megabytes
AllocateMem (1024); // Allocate in Kilobytes
// Now that memory is full, try calling function that has 10K stack
CallFunctionWithBigStack();
return 0;
}
所以我的问题是:
内存不足会导致“堆栈溢出”,尤其是在堆栈上没有太多内容且没有递归的情况下。
还有什么可能导致 srand() 进入导致堆栈溢出的函数迭代。
如果“堆栈溢出”不能被异常处理程序捕获,如果内存不足时会发生这种情况,该如何处理。
【问题讨论】:
标签: c multithreading visual-c++ memory stack-overflow