步骤:
1) 打开WinDBG并将之Attach 到crash的程序进程
2) 输入产生dump 文件的命令
WinDBG产生dump 文件的命令是 .dump ,可以选择不同的参数来生成不同类型的dump文件。
选项(1): /m
命令行示例:.dump /m C:\dumps\myapp.dmp
注解: 缺省选项,生成标准的minidump, 转储文件通常较小,便于在网络上通过邮件或其他方式传输。 这种文件的信息量较少,只包含系统信息、加载的模块(DLL)信息、 进程信息和线程信息。
选项(2): /ma
命令行示例:.dump /ma C:\dumps\myapp.dmp
注解: 带有尽量多选项的minidump(包括完整的内存内容、句柄、未加载的模块,等等),文件很大,但如果条件允许(本机调试,局域网环境), 推荐使用这中dump。
选项(3):/mFhutwd
命令行示例:.dump /mFhutwd C:\dumps\myapp.dmp
注解:带有数据段、非共享的读/写内存页和其他有用的信息的minidump。包含了通过minidump能够得到的最多的信息。是一种折中方案。
上面介绍如如何用WinDBG 生成crash dump 《WinDBG 技巧:如何生成Dump 文件(.dump 命令) 》,但是用户机器上通常不安装WinDBG, 而且多数用户也不知道怎么使用WinDBG。 所以最好是自己程序里面能够捕捉exception/crash,并且生成crash dump,然后通过网络传回到自己服务器。
捕捉exception 可以用API 函数 SetUnhandledExceptionFilter 。
生成crash dump 可以用DbgHelp.dll 里面的MiniDumpWriteDump 函数。
LPTOP_LEVEL_EXCEPTION_FILTER WINAPI SetUnhandledExceptionFilter( __in LPTOP_LEVEL_EXCEPTION_FILTER lpTopLevelExceptionFilter )
BOOL WINAPI MiniDumpWriteDump( __in HANDLE hProcess, __in DWORD ProcessId, __in HANDLE hFile, __in MINIDUMP_TYPE DumpType, __in PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, __in PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, __in PMINIDUMP_CALLBACK_INFORMATION CallbackParam )
【代码实例】
#include <dbghelp.h>
#include <shellapi.h>
#include <shlobj.h>
// 自定义的exectpion filter
LONG WINAPI MyUnhandledExceptionFilter(struct _EXCEPTION_POINTERS*pExceptionPointers)
{
SetErrorMode( SEM_NOGPFAULTERRORBOX )
//收集信息
CStringW strBuild
strBuild.Format(L"Build: %s %s", __DATE__, __TIME__)
CStringW strError
HMODULE hModule
WCHAR szModuleName[MAX_PATH] = L""
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,(LPCWSTR)pExceptionPointers->ExceptionRecord->ExceptionAddress,&hModule)
GetModuleFileName(hModule, szModuleName, ARRAYSIZE(szModuleName))
strError.AppenedFormat(L"%s %d , %d ,%d.",szModuleName,pExceptionPointers->ExceptionRecord->ExceptionCode,pExceptionPointers->ExceptionRecord->ExceptionFlags,pExceptionPointers->ExceptionRecord->ExceptionAddress)
//生成 mini crash dump
BOOL bMiniDumpSuccessful
WCHAR szPath[MAX_PATH]
WCHAR szFileName[MAX_PATH]
WCHAR* szAppName = L"AppName"
WCHAR* szVersion = L"v1.0"
DWORD dwBufferSize = MAX_PATH
HANDLE hDumpFile
SYSTEMTIME stLocalTime
MINIDUMP_EXCEPTION_INFORMATION ExpParam
GetLocalTime( &stLocalTime )
GetTempPath( dwBufferSize, szPath )
StringCchPrintf( szFileName, MAX_PATH, L"%s%s", szPath, szAppName)
CreateDirectory( szFileName, NULL )
StringCchPrintf( szFileName, MAX_PATH, L"%s%s\\%s-%04d%02d%02d-%02d%02d%02d-%ld-%ld.dmp",
szPath, szAppName, szVersion,
stLocalTime.wYear, stLocalTime.wMonth, stLocalTime.wDay,
stLocalTime.wHour, stLocalTime.wMinute,stLocalTime.wSecond,
GetCurrentProcessId(), GetCurrentThreadId())
hDumpFile = CreateFile(szFileName, GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_WRITE|FILE_SHARE_READ, 0, CREATE_ALWAYS, 0,0)
MINIDUMP_USER_STREAM UserStream[2]
MINIDUMP_USER_STREAM_INFORMATION UserInfo
UserInfo.UserStreamCount = 1
UserInfo.UserStreamArray = UserStream
UserStream[0].Type = CommentStreamW
UserStream[0].BufferSize = strBuild.GetLength()*sizeof(WCHAR)
UserStream[0].Buffer = strBuild.GetBuffer()
UserStream[1].Type = CommentStreamW
UserStream[1].BufferSize = strError.GetLength()*sizeof(WCHAR)
UserStream[1].Buffer = strError.GetBuffer()
ExpParam.ThreadId = GetCurrentThreadId()
ExpParam.ExceptionPointers = pExceptionPointers
ExpParam.ClientPointers = TRUE
MINIDUMP_TYPE MiniDumpWithDataSegs = MiniDumpNormal
| MiniDumpWithHandleData
| MiniDumpWithUnloadedModules
| MiniDumpWithIndirectlyReferencedMemory
| MiniDumpScanMemory
| MiniDumpWithProcessThreadData
| MiniDumpWithThreadInfo
bMiniDumpSuccessful = MiniDumpWriteDump(GetCurrentProcess(),GetCurrentProcessId(),
hDumpFile, MiniDumpWithDataSegs, &ExpParam, NULL,NULL)
// 上传mini dump 到自己服务器(略)
...
return EXCEPTION_CONTINUE_SEARCH//或者 EXCEPTION_EXECUTE_HANDLER 关闭程序
}
int _tmain()
{
// 设置 execption filter
SetUnhandledExceptionFilter(MyUnhandledExceptionFilter)
....
return 0
}
正常情况下不会生成dump,需要自己在程序中添加代码实现,一般是利用MS的dbghelp.dll提供的DbgHelpCreateUserDump来生成,用WinDbg来分析,期间需要编译程序生成的.pdb文件。可以参考BlackBox、google breakpad等
crash 文件生成的路径:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug]
"Auto"="0"
"Debugger"="\"D:\\WinDBG\\ntsd.exe\" -p %ld -e %ld -g -noio -c \".dump /ma /u d:\\dbgdmp\\dmp.dmpq"
"UserDebuggerHotKey"=dword:00000000
转载仅供参考,版权属于原作者。祝你愉快,满意请采纳哦
iOS开发中遇到程序崩溃是很正常的事情,如何在程序崩溃时捕获到异常信息并通知开发者?
下面就介绍如何在iOS中实现:
1. 在程序启动时加上一个异常捕获监听,用来处理程序崩溃时的`回调动作
复制代码 代码如下:
NSSetUncaughtExceptionHandler (&UncaughtExceptionHandler)
官方文档介绍:Sets the top-level error-handling function where you can perform last-minute logging before the program terminates.
UncaughtExceptionHandler是一个函数指针,该函数需要我们实现,可以取自己想要的名字。当程序发生异常崩溃时,该函数会得到调用,这跟C,C++中的回调函数的概念是一样的。
2. 实现自己的处理函数
复制代码 代码如下:
void UncaughtExceptionHandler(NSException *exception) {
NSArray *arr = [exception callStackSymbols]//得到当前调用栈信息
NSString *reason = [exception reason]//非常重要,就是崩溃的原因
NSString *name = [exception name]//异常类型
NSLog(@"exception type : %@ n crash reason : %@ n call stack info : %@", name, reason, arr)
}
以上代码很简单,但是带来的作用是非常大的。
Android系统的“程序异常退出”,给应用的用户体验造成不良影响。为了捕获应用运行时异常并给出友好提示,便可继承UncaughtExceptionHandler类来处理。通过Thread.setDefaultUncaughtExceptionHandler()方法将异常处理类设置到线程上即可。
1、异常处理类,代码如下:
[java] view plaincopy
public class CrashHandler implements UncaughtExceptionHandler {
public static final String TAG = "CrashHandler"
private static CrashHandler INSTANCE = new CrashHandler()
private Context mContext
private Thread.UncaughtExceptionHandler mDefaultHandler
private CrashHandler() {
}
public static CrashHandler getInstance() {
return INSTANCE
}
public void init(Context ctx) {
mContext = ctx
mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler()
Thread.setDefaultUncaughtExceptionHandler(this)
}
@Override
public void uncaughtException(Thread thread, Throwable ex) {
// if (!handleException(ex) &&mDefaultHandler != null) {
// mDefaultHandler.uncaughtException(thread, ex)
// } else {
// android.os.Process.killProcess(android.os.Process.myPid())
// System.exit(10)
// }
System.out.println("uncaughtException")
new Thread() {
@Override
public void run() {
Looper.prepare()
new AlertDialog.Builder(mContext).setTitle("提示").setCancelable(false)
.setMessage("程序崩溃了...").setNeutralButton("我知道了", new OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
System.exit(0)
}
})
.create().show()
Looper.loop()
}
}.start()
}
/**
* 自定义错误处理,收集错误信息 发送错误报告等 *** 作均在此完成. 开发者可以根据自己的情况来自定义异常处理逻辑
*
* @param ex
* @return true:如果处理了该异常信息否则返回false
*/
private boolean handleException(Throwable ex) {
if (ex == null) {
return true
}
// new Handler(Looper.getMainLooper()).post(new Runnable() {
// @Override
// public void run() {
// new AlertDialog.Builder(mContext).setTitle("提示")
// .setMessage("程序崩溃了...").setNeutralButton("我知道了", null)
// .create().show()
// }
// })
return true
}
}
2、线程绑定异常处理类
[java] view plaincopy
public class CrashHandlerActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main)
CrashHandler crashHandler = CrashHandler.getInstance()
crashHandler.init(this) //传入参数必须为Activity,否则AlertDialog将不显示。
// 创建错误
throw new NullPointerException()
}
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)