2020-03-08
软件调试运行时有错误弹框可以直接看到
软件只有一个按钮,用作错误测试,点击按钮后执行左侧代码,会弹出错误
很明显提示变量附近栈损坏,此时查看断点位置代码,因为只给了5个字节的空间却拷贝了超出5字节大小的内容,很容易定位到错误并修改代码
软件是exe直接运行,此时不在vs内运行,且该客户机没有代码,但是需要有vs
假设程序很大,无法从提示的szBuf附近栈损坏直接定位,此时提示信息中说点击重试可以调试软件,win
7显示可能不同不过类似
此时打开vs,选择工具,附加调试进程
找到对应的应用程序,点击附加
此时什么也没有显示,但是vs明显处于运行状态
此时点击报错的重试
vs发生如下变化,点击中断
因为此时没有代码所以显示的汇编代码,点击调试,将存储另存为
将存储存到桌面,之后关闭vs
此时拿到了程序崩溃时的环境,拷贝生成的dmp文件到拥有代码的机器查看
将拷贝的dmp文件放到有代码的机器的对应软件目录的debug目录下,因为此目录有pdb文件,不需用再去设置代码路径之类的信息了
选择vs打开dmp文件,显示如下,点击右边的使用仅限本机调试
显示如下,此时点击中断
此时类似于本机调试时的报错,不光显示崩溃的位置而且对应的变量此时内容可以监控,可以查看内存,线程等信息
针对有些错误直接无响应并且闪退的问题,需要程序自动生成dump文件
错误示例1:
将错误代码更改成除0错误,debug版exe运行直接闪退,(release版本没有反应,未出现报错)
错误示例2:
0地址写入,debug版本和release版本都直接闪退
针对上面两种错误以及类似的错误就需要代码直接生成dmp文件了
添加新的类,如下,类名是Undump文件,将下面头文件和cpp文件粘贴进去,不需要写代码调用,此种方法也可以用于上面弹框的报错
之后重新编译运行软件,软件闪退,但是此时出现了一个dmp文件
此时拷贝该dmp文件执行上面相同的操作,定位错误内容如下
头文件
#pragma once
#include <Windows.h>
class CMiniDump
{
public:
CMiniDump(void);
virtual ~CMiniDump(void);
protected:
static BOOL GetModulePath(LPTSTR lpBuf, DWORD dwBufSize);
static LONG WINAPI MyUnhandledExceptionFilter(EXCEPTION_POINTERS* ExceptionInfo);
};
extern CMiniDump mindump;
cpp文件
#include "stdafx.h"
#include "Undump.h"
#include <imagehlp.h>
#pragma comment(lib,"DbgHelp.lib")
CMiniDump::CMiniDump(void)
{
SetUnhandledExceptionFilter(&CMiniDump::MyUnhandledExceptionFilter);
}
CMiniDump::~CMiniDump(void)
{
}
LONG WINAPI CMiniDump::MyUnhandledExceptionFilter(EXCEPTION_POINTERS* ExceptionInfo)
{
TCHAR sModulePath[MAX_PATH] = { 0 };
GetModulePath(sModulePath, MAX_PATH);
TCHAR sFileName[MAX_PATH] = { 0 };
SYSTEMTIME systime = { 0 };
GetLocalTime(&systime);
_stprintf_s(sFileName, _T("%04d%02d%02d-%02d%02d%02d.dmp"),
systime.wYear, systime.wMonth, systime.wDay, systime.wHour, systime.wMinute, systime.wSecond);
_tcscat_s(sModulePath, sFileName);
HANDLE lhDumpFile = CreateFile(sModulePath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
MINIDUMP_EXCEPTION_INFORMATION loExceptionInfo;
loExceptionInfo.ExceptionPointers = ExceptionInfo;
loExceptionInfo.ThreadId = GetCurrentThreadId();
loExceptionInfo.ClientPointers = FALSE;
MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), lhDumpFile, MiniDumpNormal, &loExceptionInfo, NULL, NULL);
CloseHandle(lhDumpFile);
return EXCEPTION_EXECUTE_HANDLER;
}
BOOL CMiniDump::GetModulePath(LPTSTR lpBuf, DWORD dwBufSize)
{
TCHAR sModuleName[MAX_PATH] = { 0 };
GetModuleFileName(NULL, sModuleName, MAX_PATH);
TCHAR* pChar = _tcsrchr(sModuleName, _T(‘\\‘));
if (NULL != pChar)
{
int iPos = pChar - sModuleName;
sModuleName[iPos + 1] = _T(‘\0‘);
_tcscpy_s(lpBuf, dwBufSize, sModuleName);
return TRUE;
}
return FALSE;
}
CMiniDump mindump;
如下链接
https://www.cnblogs.com/haihai1203/p/3395137.html
原文:https://www.cnblogs.com/fengtao918/p/14387025.html