c - 当内存非常低时,线程内的 srand() 会导致堆栈溢出

标签 c multithreading visual-c++ memory stack-overflow

这是在 Windows XP 上的 VisualStudio 中用 C/C++ 开发的多线程应用程序。

用户报告说它因错误“Stack Overflow”而崩溃

经过调试,发现当计算机内存不足时,在其中一个线程中调用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++

所以我们可以清楚地看到一个调用 block 进行递归,最终导致“堆栈溢出”

我想知道内存不足是否真的会导致堆栈溢出。因此,我编写了试用代码,分配内存直到内存满,然后调用具有大堆栈分配的函数。

但是,程序并没有失败。下面是代码:

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;
}

所以我的问题是:

  1. 内存不足会导致“堆栈溢出”,特别是当堆栈上没有太多内容且没有递归时。

  2. 还有什么可能导致 srand() 进入函数迭代,从而导致堆栈溢出。

  3. 如果异常处理程序无法捕获“堆栈溢出”,如果内存不足时会发生这种情况,该如何处理。

最佳答案

  1. 在这种情况下,srand 正在调用另一个因内存不足而失败的函数,并且无法很好地从中恢复。因此就会出现递归和堆栈溢出。
  2. 请参阅答案 1。这看起来像是 C 运行时库中的错误。

您尝试过哪种异常处理?

关于c - 当内存非常低时,线程内的 srand() 会导致堆栈溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24080427/

相关文章:

c++ - 将clock_gettime移植到windows

multithreading - Storm Spouts 是否应该仅使用调用 Spout.nextTuple 的线程发出输出?

c++ - 相当于 C++ 标准库模板 (STL) 中的 CreateProcess()

visual-studio - 如何在Windows 7上安装VS6,SP5和Proc Pack?

c - TCP套接字服务器

c - 如何使用 C 分别获取文本文件的每一行

c - 如何将函数指针作为参数传递?

C#:异常后停止线程

java - 将输入流传递给其他线程时读取失败

c++ - std::function/std::bind 的生命周期管理(在 Windows PostMessage 中传递一个仿函数作为 lparam)