
Windbg生成dump文件的方法:程序崩溃(crash)的时候, 为了以后能够调试分析问题, 可以使用WinDBG要把当时程序内存空间数据都保存下来,生成的文件称为dump 文件。 步骤:1) 打开WinDBG并将之Attach 到crash的程序进程2) 输入产生dump 文件的命令WinDBG产生dump 文件的命令是 dump ,可以选择不同的参数来生成不同类型的dump文件。选项(1): /m命令行示例:dump /m C:\dumps\myappdmp注解: 缺省选项,生成标准的minidump, 转储文件通常较小,便于在网络上通过邮件或其他方式传输。 这种文件的信息量较少,只包含系统信息、加载的模块(DLL)信息、 进程信息和线程信息。选项(2): /ma命令行示例:dump /ma C:\dumps\myappdmp注解: 带有尽量多选项的minidump(包括完整的内存内容、句柄、未加载的模块,等等),文件很大,但如果条件允许(本机调试,局域网环境), 推荐使用这中dump。选项(3):/mFhutwd命令行示例:dump /mFhutwd C:\dumps\myappdmp注解:带有数据段、非共享的读/写内存页和其他有用的信息的minidump。包含了通过minidump能够得到的最多的信息。是一种折中方案那怎么自动生成dump文件呢,比如对方的电脑没有windbg,这里用到一个window系统自带工具,DrWatson运行方式很简单:直接run-输入drwtsn32 -i就可以了,会提示这样的:这个命令真难记,实话,记华生医生吧,福尔摩斯中的如果有程序崩溃,会自动生成dump,这时再输入drwtsn32就会运行这个程序:找到对应路径的DMP文件就行了,一般放在如下路径:C:\Documents and Settings\All Users\Application Data\Microsoft\Dr Watson以下实例来自AWD代码:Copyright (c) Advanced Windows Debugging (ISBN 0321374460) from Addison-Wesley Professional All rights reserved THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE --/ #include "stdafxh" #include <windowsh> #include <stdioh> #include <conioh> VOID SimulateMemoryCorruption ( ) ; class CAppInfo { public: CAppInfo(LPWSTR wszAppName, LPWSTR wszVersion) { m_wszAppName=wszAppName; m_wszVersion=wszVersion; } VOID PrintAppInfo() { wprintf(L"\nFull application Name: %s\n", m_wszAppName); wprintf(L"Version: %s\n", m_wszVersion); } private: LPWSTR m_wszAppName ; LPWSTR m_wszVersion ; } ; CAppInfo g_AppInfo ; int __cdecl wmain (int argc, WCHAR args[]) { wint_t iChar = 0 ; g_AppInfo = new CAppInfo(L"Memory Corruption Sample", L"10" ); if(!g_AppInfo) { return 1; } wprintf(L"Press: \n"); wprintf(L" 1 To display application information\n"); wprintf(L" 2 To simulated memory corruption\n"); wprintf(L" 3 To exit\n\n\n>"); while((iChar=_getwche())!='3') { switch(iChar) { case '1': g_AppInfo->PrintAppInfo(); break; case '2': SimulateMemoryCorruption(); wprintf(L"\nMemory Corruption completed\n"); break; default: wprintf(L"\nInvalid option\n"); } wprintf(L"\n\n> "); } return 0; } VOID SimulateMemoryCorruption ( ) { char pszWrite="Corrupt"; BYTE p=(BYTE) g_AppInfo; CopyMemory(p, pszWrite, strlen(pszWrite)); }
调试Dump文件很简单,双击自动打开VC然后F7运行。
但是中间要注意很多事情。
1。Dump文件放在哪里
Dump文件不用非要放在你编译出来的位置,你完全可以建立一个新的文件夹来放它。
2。要恢复当时的现场
可能你要问,怎么可能,这个dump文件可是用户发给我的,我不可能去用户家里调试吧?
这个恢复现场可不是指的非要到那台机器上去,而是要把产生dump文件对应的二进制文件拿到。
但是恢复现场需要所有的二进制文件都要对应,你一定要有导致用户崩溃的那些Exe和Dll。既然是你发布的程序,Exe文件当然你会有。所以这里只考虑Dll就行了。
Dump文件中记录了所有dll文件的版本号和时间戳,所以你一定可以同过某种途径拿到它。如果你能从用户那里拿到最好,如果不方便,用户不可能用的是我们平常不常用的 *** 作系统,所以找个有对应系统的机器一般都会有。但是记住不光是文件名称要一致,还要核对版本和时间戳,如果不同一样没有办法用。
Dumpsys是Android系统自带的一个调试工具,可以通过该工具查看系统服务的状态信息,包括WiFi开关是否开启等。在使用dumpsys查看WiFi开关状态时,需要按照以下步骤进行:
1 打开终端或命令行窗口,输入adb shell命令进入Android系统的shell环境。
2 输入dumpsys wifi命令,查看WiFi服务的状态信息。
3 查看WiFi服务状态信息中的Wi-Fi enabled字段,该字段的值为true表示WiFi开关已开启,值为false表示WiFi开关已关闭。
通过使用dumpsys工具,可以快速方便地查看WiFi开关是否开启,从而判断是否可以正常连接WiFi网络。在Android开发和调试过程中,dumpsys是一个非常有用的工具,可以帮助开发者快速定位和解决问题。
一般这种情况都是因为数组越界访问,空指针或是野指针读写造成的。程序小的话还比较好办,对着源代码仔细检查就能解决。但是对于代码量较大的程序,里边包含N多函数调用,N多数组指针访问,这时想定位问题就不是很容易了(此时牛人依然可以通过在适当位置打printf加二分查找的方式迅速定位:P)。懒人的话还是直接GDB搞起吧。 神马是Core Dump文件偶尔就能听见某程序员同学抱怨“擦,又出Core了!”。简单来说,core dump说的是 *** 作系统执行的一个动作,当某个进程因为一些原因意外终止(crash)的时候, *** 作系统会将这个进程当时的内存信息转储(dump)到磁盘上1。产生的文件就是core文件了,一般会以corexxx形式命名。 如何产生Core Dump 发生doredump一般都是在进程收到某个信号的时候,Linux上现在大概有60多个信号,可以使用 kill -l 命令全部列出来。sagi@sagi-laptop:~$ kill -l 1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP 6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1 11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM 16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP 21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ 26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR 31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3 38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8 43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13 48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12 53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7 58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2 63) SIGRTMAX-1 64) SIGRTMAX针对特定的信号,应用程序可以写对应的信号处理函数。如果不指定,则采取默认的处理方式, 默认处理是coredump的信号如下:3)SIGQUIT 4)SIGILL 6)SIGABRT 8)SIGFPE 11)SIGSEGV 7)SIGBUS 31)SIGSYS 5)SIGTRAP 24)SIGXCPU 25)SIGXFSZ 29)SIGIOT 我们看到SIGSEGV在其中,一般数组越界或是访问空指针都会产生这个信号。另外虽然默认是这样的,但是你也可以写自己的信号处理函数改变默认行为,更多信号相关可以看参考链接33。 上述内容只是产生coredump的必要条件,而非充分条件。要产生core文件还依赖于程序运行的shell,可以通过ulimit -a命令查看,输出内容大致如下:sagi@sagi-laptop:~$ ulimit -a core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 20 file size (blocks, -f) unlimited pending signals (-i) 16382 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 8192 cpu time (seconds, -t) unlimited max user processes (-u) unlimited virtual memory (kbytes, -v) unlimited file locks (-x) unlimited 看到第一行了吧,core file size,这个值用来限制产生的core文件大小,超过这个值就不会保存了。我这里输出是0,也就是不会保存core文件,即使产生了,也保存不下来==! 要改变这个设置,可以使用ulimit -c unlimited。 OK, 现在万事具备,只缺一个能产生Core的程序了,介个对C程序员来说太容易了。#include ; #include ; int crash() { char xxx = "crash!!"; xxx[1] = 'D'; // 写只读存储区! return 2; } int foo() { return crash(); } int main() { return foo(); } 上手调试 上边的程序编译的时候有一点需要注意,需要带上参数-g, 这样生成的可执行程序中会带上足够的调试信息。编译运行之后你就应该能看见期待已久的“Segment Fault(core dumped)”或是“段错误 (核心已转储)”之类的字眼了。看看当前目录下是不是有个core或是corexxx的文件。祭出linux下经典的调试器GDB,首先带着core文件载入程序:gdb exefile core,这里需要注意的这个core文件必须是exefile产生的,否则符号表会对不上。载入之后大概是这个样子的:sagi@sagi-laptop:~$ gdb coredump core Core was generated by /coredump' Program terminated with signal 11, Segmentation fault #0 0x080483a7 in crash () at coredumpc:8 8 xxx[1] = 'D'; (gdb)我们看到已经能直接定位到出core的地方了,在第8行写了一个只读的内存区域导致触发Segment Fault信号。在载入core的时候有个小技巧,如果你事先不知道这个core文件是由哪个程序产生的,你可以先随便找个代替一下,比如/usr/bin/w就是不错的选择。比如我们采用这种方法载入上边产生的core,gdb会有类似的输出:sagi@sagi-laptop:~$ gdb /usr/bin/w core Core was generated by /coredump' Program terminated with signal 11, Segmentation fault #0 0x080483a7 in () (gdb)可以看到GDB已经提示你了,这个core是由哪个程序产生的。 GDB 常用 *** 作 上边的程序比较简单,不需要另外的 *** 作就能直接找到问题所在。现实却不是这样的,常常需要进行单步跟踪,设置断点之类的 *** 作才能顺利定位问题。下边列出了GDB一些常用的 *** 作。 启动程序:run设置断点:b 行号|函数名删除断点:delete 断点编号禁用断点:disable 断点编号启用断点:enable 断点编号单步跟踪:next 也可以简写 n单步跟踪:step 也可以简写 s打印变量:print 变量名字设置变量:set var=value查看变量类型:ptype var顺序执行到结束:cont顺序执行到某一行: util lineno打印堆栈信息:bt
我也是看比人的,你看有没有帮助。
正常情况下不会生成dump,需要自己在程序中添加代码实现,一般是利用MS的dbghelpdll提供的DbgHelpCreateUserDump来生成,用WinDbg来分析,期间需要你编译程序生成的pdb文件,总之比较麻烦。可以参考BlackBox、google breakpad等
以上就是关于如何手动产生windows系统的完全内存dump全部的内容,包括:如何手动产生windows系统的完全内存dump、怎么能让我的程序在崩溃时生成dump文件、dumpsys查看wifi开关是否开启等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)