几十万次通讯后,没有任何征兆和想象,随机的会突然退出. 程序在运行过程中,
我通过任务管理器看这个程序的内存使用,CPU占用,线程数,句柄等各项指标都正常.
有高手,能出主意,我该如何可以知道问题在哪里吗?
15 个解决方案
#1
崩溃?
#2
1:写程序日志
2:把程序在debug状态下运行,看出错的时候是否能断点到你出错的地方
2:把程序在debug状态下运行,看出错的时候是否能断点到你出错的地方
#3
LPTOP_LEVEL_EXCEPTION_FILTER g_ExceptionFilter = NULL;
LONG WINAPI MyExceptionFilter (struct _EXCEPTION_POINTERS* lpExceptionInfo)
{
#ifdef _DEBUG
DebugBreak();
#endif
FILE *fp =fopen("d:\\error.dat","wb");
struct _EXCEPTION_RECORD* pER = lpExceptionInfo->ExceptionRecord;
while( pER )
{
fwrite( pER, 1, sizeof(EXCEPTION_RECORD), fp );
pER = pER->ExceptionRecord;
}
fwrite(lpExceptionInfo->ContextRecord, 1, sizeof(CONTEXT), fp );
fclose(fp);
LONG lResult = lpExceptionInfo -> ExceptionRecord ->ExceptionCode;
DWORD nThreadId = GetCurrentThreadId();
DWORD nProcessId= GetCurrentProcessId();
CString CsErrDescr;
CsErrDescr.Format("Exception:%d at CMD 0x%.8x<ThreadId:%d>",
lpExceptionInfo->ExceptionRecord->ExceptionCode,
lpExceptionInfo->ExceptionRecord->ExceptionAddress,
nThreadId);
AfxMessageBox(CsErrDescr);
if(g_ExceptionFilter)
return g_ExceptionFilter(lpExceptionInfo);
return lResult;
}
BOOL CTest0App::InitInstance()
{
g_ExceptionFilter = SetUnhandledExceptionFilter( MyExceptionFilter);
..........
}
先加这些看看
#4
用F5来运行,如果是只有Release版本出错,则在工程属性Linker,Debugging中,把Generate Debug info设为yes
看程序退出的时候,vc里面有什么错误的提示。
看程序退出的时候,vc里面有什么错误的提示。
#5
生成符号文件pdb,然后用windbg调试,崩溃时能捕捉到
#6
1 写个测试程序 疯狂的调你的接口函数(各种正确及错误的数据) 你的程序运行在调试模式下
2 用dump
2 用dump
#7
可能要看看你的问题究竟是出在哪方面?是否与硬件有关还是同代码相关。如果同代码相关的话好办。
通过逻辑上的二分法来不断定位你的问题究竟出在哪段代码上。
通过逻辑上的二分法来不断定位你的问题究竟出在哪段代码上。
#8
先设置*异常过滤,
然后再用MiniDump.
然后再用MiniDump.
#9
如果是debug,那么有很多种方法:
1)可以使用循环日志的方式,输出信息。(这个方法对release也同样有效)
2)看有没有错误的代码,如0xc0005等信息,如果有有用的信息,则可以使用make文件,查找一下程序的大概位置。
3)可以使用*.pdb,但出现错误的时候,选择继续,断到程序出错的地方。
4)可以使用日志,输出调用堆栈的内容。
1)可以使用循环日志的方式,输出信息。(这个方法对release也同样有效)
2)看有没有错误的代码,如0xc0005等信息,如果有有用的信息,则可以使用make文件,查找一下程序的大概位置。
3)可以使用*.pdb,但出现错误的时候,选择继续,断到程序出错的地方。
4)可以使用日志,输出调用堆栈的内容。
#10
请问楼上的大侠,如何使用日志,输出调用堆栈的内容呢?
#11
1)输出日志,主要是把日志存放到一个链表中,这个链表的大小可以设置,当大于最大值的时候,再删除前面的若干条,然后继续使用这个日志。在debug环境下,可以使用vc一个调试参数,输出一些信息,不过需要注意把所有的TRACE()都关闭掉。
2)至于如何输出调用堆栈的内容,网上有现成的代码,可以搜索以下。
2)至于如何输出调用堆栈的内容,网上有现成的代码,可以搜索以下。
#13
非常感谢大家的回音,根据F5运行,居然发现是:
//...
::EnterCriticalSection(&pContext->Lock);
//...
会不定时的出错,在出错时候,我检查了pContext指针是有效的,
EnterCriticalSection和LeaveCriticalSection都是正常的使用.
难道EnterCriticalSection这类的函数在运行太多次后也有可能出错?!
并且这样的函数一出错,如果不使用try捕捉,当发生出错时候,进程直接就结束的.
//...
::EnterCriticalSection(&pContext->Lock);
//...
会不定时的出错,在出错时候,我检查了pContext指针是有效的,
EnterCriticalSection和LeaveCriticalSection都是正常的使用.
难道EnterCriticalSection这类的函数在运行太多次后也有可能出错?!
并且这样的函数一出错,如果不使用try捕捉,当发生出错时候,进程直接就结束的.
#14
这个不一定就是这段代码出现了错误。
可能是因为同步没有做好,而引起的错误。
可能是因为同步没有做好,而引起的错误。
#15
凤矶写的东西不错
#1
崩溃?
#2
1:写程序日志
2:把程序在debug状态下运行,看出错的时候是否能断点到你出错的地方
2:把程序在debug状态下运行,看出错的时候是否能断点到你出错的地方
#3
LPTOP_LEVEL_EXCEPTION_FILTER g_ExceptionFilter = NULL;
LONG WINAPI MyExceptionFilter (struct _EXCEPTION_POINTERS* lpExceptionInfo)
{
#ifdef _DEBUG
DebugBreak();
#endif
FILE *fp =fopen("d:\\error.dat","wb");
struct _EXCEPTION_RECORD* pER = lpExceptionInfo->ExceptionRecord;
while( pER )
{
fwrite( pER, 1, sizeof(EXCEPTION_RECORD), fp );
pER = pER->ExceptionRecord;
}
fwrite(lpExceptionInfo->ContextRecord, 1, sizeof(CONTEXT), fp );
fclose(fp);
LONG lResult = lpExceptionInfo -> ExceptionRecord ->ExceptionCode;
DWORD nThreadId = GetCurrentThreadId();
DWORD nProcessId= GetCurrentProcessId();
CString CsErrDescr;
CsErrDescr.Format("Exception:%d at CMD 0x%.8x<ThreadId:%d>",
lpExceptionInfo->ExceptionRecord->ExceptionCode,
lpExceptionInfo->ExceptionRecord->ExceptionAddress,
nThreadId);
AfxMessageBox(CsErrDescr);
if(g_ExceptionFilter)
return g_ExceptionFilter(lpExceptionInfo);
return lResult;
}
BOOL CTest0App::InitInstance()
{
g_ExceptionFilter = SetUnhandledExceptionFilter( MyExceptionFilter);
..........
}
先加这些看看
#4
用F5来运行,如果是只有Release版本出错,则在工程属性Linker,Debugging中,把Generate Debug info设为yes
看程序退出的时候,vc里面有什么错误的提示。
看程序退出的时候,vc里面有什么错误的提示。
#5
生成符号文件pdb,然后用windbg调试,崩溃时能捕捉到
#6
1 写个测试程序 疯狂的调你的接口函数(各种正确及错误的数据) 你的程序运行在调试模式下
2 用dump
2 用dump
#7
可能要看看你的问题究竟是出在哪方面?是否与硬件有关还是同代码相关。如果同代码相关的话好办。
通过逻辑上的二分法来不断定位你的问题究竟出在哪段代码上。
通过逻辑上的二分法来不断定位你的问题究竟出在哪段代码上。
#8
先设置*异常过滤,
然后再用MiniDump.
然后再用MiniDump.
#9
如果是debug,那么有很多种方法:
1)可以使用循环日志的方式,输出信息。(这个方法对release也同样有效)
2)看有没有错误的代码,如0xc0005等信息,如果有有用的信息,则可以使用make文件,查找一下程序的大概位置。
3)可以使用*.pdb,但出现错误的时候,选择继续,断到程序出错的地方。
4)可以使用日志,输出调用堆栈的内容。
1)可以使用循环日志的方式,输出信息。(这个方法对release也同样有效)
2)看有没有错误的代码,如0xc0005等信息,如果有有用的信息,则可以使用make文件,查找一下程序的大概位置。
3)可以使用*.pdb,但出现错误的时候,选择继续,断到程序出错的地方。
4)可以使用日志,输出调用堆栈的内容。
#10
请问楼上的大侠,如何使用日志,输出调用堆栈的内容呢?
#11
1)输出日志,主要是把日志存放到一个链表中,这个链表的大小可以设置,当大于最大值的时候,再删除前面的若干条,然后继续使用这个日志。在debug环境下,可以使用vc一个调试参数,输出一些信息,不过需要注意把所有的TRACE()都关闭掉。
2)至于如何输出调用堆栈的内容,网上有现成的代码,可以搜索以下。
2)至于如何输出调用堆栈的内容,网上有现成的代码,可以搜索以下。
#12
#13
非常感谢大家的回音,根据F5运行,居然发现是:
//...
::EnterCriticalSection(&pContext->Lock);
//...
会不定时的出错,在出错时候,我检查了pContext指针是有效的,
EnterCriticalSection和LeaveCriticalSection都是正常的使用.
难道EnterCriticalSection这类的函数在运行太多次后也有可能出错?!
并且这样的函数一出错,如果不使用try捕捉,当发生出错时候,进程直接就结束的.
//...
::EnterCriticalSection(&pContext->Lock);
//...
会不定时的出错,在出错时候,我检查了pContext指针是有效的,
EnterCriticalSection和LeaveCriticalSection都是正常的使用.
难道EnterCriticalSection这类的函数在运行太多次后也有可能出错?!
并且这样的函数一出错,如果不使用try捕捉,当发生出错时候,进程直接就结束的.
#14
这个不一定就是这段代码出现了错误。
可能是因为同步没有做好,而引起的错误。
可能是因为同步没有做好,而引起的错误。
#15
凤矶写的东西不错