Showing posts with label debug. Show all posts
Showing posts with label debug. Show all posts

Friday, June 17, 2011

[Windows]dbg

cheating sheet ntsd: user mode debugger
kd: kernel mode debugger
windbg: GUI wrapp for ntsd and kd

最基本命令
.hh: 查看help
k: show call stack
r: show register
Q: quit dbg
bp: set breakpoint
  • bp foo!main
  • bp `source.c:31`
  • ba: set data breakpoint

p: step
pc: step to next call


kb: Dump the stack with Params
kn: Dump the stack with Frame #
kd: Dump stack dissassembly
~#s: Change to thread (Example: ~3s)
dd # - Dump the data (Example: dd 01f056548)
bl: list breakpoints
bd: disable breakpoint
bc: remove breakpoint
lm: system modules
x foo!*: 查看所有module foo的symbol
.sympath: 查看当前sympath
!sympath+“\\your_computer\path\to\your\pdb”: 添加路径到sympath中
!sym noisy/quiet: Generate verbose output from symbol loader
.srcpath: 查看当前srcpath
!srcpath+"\\your_computer\path\to\your\pdb": 添加路径到srcpath中



Kernel Mode Extension
!symfix: 碰到说nt symbols are incorrect please fix的时候运行
!reload: 重新读入symbols 包括kernel symbols, private symbols, user symbols.
!reload foo.sys: 重新读入foo.sys这个driver的symbols
!process: 查看所有进程
!process 0 0 myprocess.exe: 查看叫myprocess.exe的进程
!thread: 查看所有线程
!driveinfo: 驱动信息
!irp: IRP
!irpfind


读取symbol
!symfix
!reload
Connected to Windows 7 7601 x64 target at (Tue Jun 21 13:22:28.221 2011 (UTC - 7:00)), ptr64 TRUE
Loading Kernel Symbols
...............................................................
................................................................
............................
Loading User Symbols
................................................................
.........................
Loading unloaded module list
..........
显示driver object (比如kbdclass)
!drvobj kbdclass
Driver object (fffffa8007370870) is for:
 \Driver\kbdclass
Driver Extension List: (id , addr)
显示driver object (比如kbdclass)的dispatch routines
!drvobj kbdclass 7
Driver object (fffffa8007370870) is for:
 \Driver\kbdclass
Driver Extension List: (id , addr)

Device Object list:
fffffa8007a31ce0  fffffa800743d6c0  

DriverEntry:   fffff8800440becc kbdclass!GsDriverEntry
DriverStartIo: 00000000 
DriverUnload:  00000000 
AddDevice:     fffff880044083b4 kbdclass!KeyboardAddDevice

Dispatch routines:
[00] IRP_MJ_CREATE                      fffff88004401dd4 kbdclass!KeyboardClassCreate
[01] IRP_MJ_CREATE_NAMED_PIPE           fffff800034b58ac nt!IopInvalidDeviceRequest
[02] IRP_MJ_CLOSE                       fffff8800440217c kbdclass!KeyboardClassClose
[03] IRP_MJ_READ                        fffff88004402804 kbdclass!KeyboardClassRead
[04] IRP_MJ_WRITE                       fffff800034b58ac nt!IopInvalidDeviceRequest
[05] IRP_MJ_QUERY_INFORMATION           fffff800034b58ac nt!IopInvalidDeviceRequest
[06] IRP_MJ_SET_INFORMATION             fffff800034b58ac nt!IopInvalidDeviceRequest
[07] IRP_MJ_QUERY_EA                    fffff800034b58ac nt!IopInvalidDeviceRequest
[08] IRP_MJ_SET_EA                      fffff800034b58ac nt!IopInvalidDeviceRequest
[09] IRP_MJ_FLUSH_BUFFERS               fffff88004401ce0 kbdclass!KeyboardClassFlush
[0a] IRP_MJ_QUERY_VOLUME_INFORMATION    fffff800034b58ac nt!IopInvalidDeviceRequest
[0b] IRP_MJ_SET_VOLUME_INFORMATION      fffff800034b58ac nt!IopInvalidDeviceRequest
[0c] IRP_MJ_DIRECTORY_CONTROL           fffff800034b58ac nt!IopInvalidDeviceRequest
[0d] IRP_MJ_FILE_SYSTEM_CONTROL         fffff800034b58ac nt!IopInvalidDeviceRequest
[0e] IRP_MJ_DEVICE_CONTROL              fffff88004408a40 kbdclass!KeyboardClassDeviceControl
[0f] IRP_MJ_INTERNAL_DEVICE_CONTROL     fffff880044082b4 kbdclass!KeyboardClassPassThrough
[10] IRP_MJ_SHUTDOWN                    fffff800034b58ac nt!IopInvalidDeviceRequest
[11] IRP_MJ_LOCK_CONTROL                fffff800034b58ac nt!IopInvalidDeviceRequest
[12] IRP_MJ_CLEANUP                     fffff88004401afc kbdclass!KeyboardClassCleanup
[13] IRP_MJ_CREATE_MAILSLOT             fffff800034b58ac nt!IopInvalidDeviceRequest
[14] IRP_MJ_QUERY_SECURITY              fffff800034b58ac nt!IopInvalidDeviceRequest
[15] IRP_MJ_SET_SECURITY                fffff800034b58ac nt!IopInvalidDeviceRequest
[16] IRP_MJ_POWER                       fffff88004409fd4 kbdclass!KeyboardClassPower
[17] IRP_MJ_SYSTEM_CONTROL              fffff8800440a364 kbdclass!KeyboardClassSystemControl
[18] IRP_MJ_DEVICE_CHANGE               fffff800034b58ac nt!IopInvalidDeviceRequest
[19] IRP_MJ_QUERY_QUOTA                 fffff800034b58ac nt!IopInvalidDeviceRequest
[1a] IRP_MJ_SET_QUOTA                   fffff800034b58ac nt!IopInvalidDeviceRequest
[1b] IRP_MJ_PNP                         fffff88004403368 kbdclass!KeyboardPnP

列出当前所有irp
!irpfind

Scanning large pool allocation table for Tag: Irp? (fffffa8005481000 : fffffa8005781000)

  Irp    [ Thread ] irpStack: (Mj,Mn)   DevObj  [Driver]         MDL Process
fffffa8007375930 [00000000] Irp is complete (CurrentLocation 4 > StackCount 3)
fffffa8004f19520 [00000000] Irp is complete (CurrentLocation 2 > StackCount 1) 0x0000000000000000
fffffa8007dcfe10 [fffffa80081438f0] irpStack: ( e,2d)  fffffa8006e6eb10 [ \Driver\AFD]
fffffa8007ecdbc0 [fffffa80088a9b60] irpStack: ( e, 0)  fffffa8006aa4da0 [ \Driver\Beep]
...

特别查看某个irp (比如地址是fffffa8007dcfe10的这个)
!irp fffffa8007dcfe10
Irp is active with 4 stacks 4 is current (= 0xfffffa8007dcffb8)
 No Mdl: System buffer=fffffa8008dc7d80: Thread fffffa80081438f0:  Irp stack trace.  
     cmd  flg cl Device   File     Completion-Context
 [  0, 0]   0  0 00000000 00000000 00000000-00000000    

   Args: 00000000 00000000 00000000 00000000
 [  0, 0]   0  0 00000000 00000000 00000000-00000000    

   Args: 00000000 00000000 00000000 00000000
 [  0, 0]   0  0 00000000 00000000 00000000-00000000    

   Args: 00000000 00000000 00000000 00000000
>[  e,2d]   5  1 fffffa8006e6eb10 fffffa80086bfa30 00000000-00000000    pending
        \Driver\AFD
   Args: fffffa80081844b0 fffffa80081844b0 fffff88003f03150 fffffa8007ecf810
最后一行显示出这个irp的major function是e 也就是IRP_MJ_DEVICE_CONTROL

查看namespace里\Driver里的内容:
!object \Driver
Object: fffff8a00008b7f0  Type: (fffffa8004e83a90) Directory
    ObjectHeader: fffff8a00008b7c0 (new version)
    HandleCount: 0  PointerCount: 107
    Directory Object: fffff8a000004dc0  Name: Driver

    Hash Address          Type          Name
    ---- -------          ----          ----
     00  fffffa8006fbae70 Driver        nvlddmkm
         fffffa80069eae70 Driver        fvevol
         fffffa8005d2e890 Driver        iaStorV
...

查看_DRIVER_OBJECT的结构
dt nt!_DRIVER_OBJECT
   +0x000 Type             : Int2B
   +0x002 Size             : Int2B
   +0x008 DeviceObject     : Ptr64 _DEVICE_OBJECT
   +0x010 Flags            : Uint4B
   +0x018 DriverStart      : Ptr64 Void
   +0x020 DriverSize       : Uint4B
   +0x028 DriverSection    : Ptr64 Void
   +0x030 DriverExtension  : Ptr64 _DRIVER_EXTENSION
   +0x038 DriverName       : _UNICODE_STRING
   +0x048 HardwareDatabase : Ptr64 _UNICODE_STRING
   +0x050 FastIoDispatch   : Ptr64 _FAST_IO_DISPATCH
   +0x058 DriverInit       : Ptr64     long 
   +0x060 DriverStartIo    : Ptr64     void 
   +0x068 DriverUnload     : Ptr64     void 
   +0x070 MajorFunction    : [28] Ptr64     long 

Tuesday, July 21, 2009

[Linux]GDB笔记

本文参考了如下资源
GDB quick reference: 一个很不错的cheatsheet
RMS的gdb tutorial
中文的gdb教程

1 最基本用法

最基本的gdb用法可以帮助你找到程序里哪里出现segment fault。首先你要在gcc编译的时候加上-ggdb选项。假定你的程序名叫foo,你可以用如下命令进入gdb开始program进行debug:
$ gdb foo
gdb会在你出现段错误的地方停下来,你会看到是哪个程序哪行语句出了问题.
2 Core Dump

发现了segment fault的话,还可以使用core dump。这样不但可以很方便的找到出问题的代码. 还可以多次重现这个错误。 首先使用以下的命令允许系统生成core文件.
$ ulimit -c unlimited
然后运行你的代码,比如叫foo, 等到segment fault发生并异常退出以后, 你会发现在foo的同一个文件夹下多了一个名字类似core.1234这样的文件。这时候运行如下命令就可以重现案发现场了
$ gdb foo core.1234

3 普通用法

r [arglist]: (重新)运行程序
b [file:]line, b [file:]function: 设置断点在line或者function
c, continue: 继续运行程序
s, step: 单步执行, 进入函数
n, next: 单步执行, 不进入函数
finish: 执行完当前frame
kill: 终止当前程序
q, Ctrl-d: 退出gdb
p [expr]: 显示表达式expr. 比如var表示变量var的内容而 &var表示变量var的内存地址
bt: 显示当前调用栈(call stack)
set args [arglist]: 设置命令行参数,从而可以直接用r(run)来执行

4 断点(breakpoit)/观察点(watchpoint)设置与管理

b [file:]line, b [file:]function: 设置断点在line或者function
watch [expr]: 设置观察点,一旦表达式expr有变化就停下来. expr通常为一个变量或者内存地址
rwatch [expr]: 设置观察点,一旦被读就停下程序
awatch [expr]: 设置观察点,一旦被读或者被写都停下程序
比如你可以使用awatch *(long*)addr来监视内存地址addr是否被读或者被写
info breakpoints/watchpoints: 查看当前设置了的断点和观察点, info watchpoints是info breakpoints的alias
enable/disable/delete [n]: 激活/禁用/删除 编号为[n]的断点/观察点

5 程序栈

bt, backtrace: 显示当前调用栈(call stack),比如
(gdb) bt
#0  0x000000010005ea07 in init (ctx=0x100622070, opts=@0x10060d078) at Utils.cpp:1678
#1  0x00000001000149ad in main (argc=3, argv=0x7fff5fbffb30) at main.cpp:591
frame: 改变frame,比如
(gdb) frame 1
#2  0x8048414 in main (argc=1, argv=0xbffffaf4) at test.c:19
19        x = func1(x);
info frame: 查看当前frame的信息
(gdb) info frame
Stack level 2, frame at 0xbffffa8c:
eip = 0x8048414 in main (test.c:19); saved eip 0x40037f5c
called by frame at 0xbffffac8, caller of frame at 0xbffffa5c 
source language c.
Arglist at 0xbffffa8c, args: argc=1, argv=0xbffffaf4
Locals at 0xbffffa8c, Previous frame's sp is 0x0
Saved registers:
ebp at 0xbffffa8c, eip at 0xbffffa90
info locals: 查看当前frame里的局部变量
(gdb) info locals
x = 30
s = 0x8048484 "Hello World!\n"
info args: 查看当前frame的调用参数
(gdb) info args
argc = 1
argv = (char **) 0xbffffaf4


6 查看变量/函数, 改变变量值

如果有一个指针变量it指向一个struct item, 查看这个struct item的内存地址:
(gdb) p it
$1 = (item *) 0x100700060
查看这个struct的内容
(gdb) p *it
$2 = {
  next = 0x100700000, 
  prev = 0x0
}
如果你有如下数组
int *array = (int *) malloc (len * sizeof (int));
你可以这样来查看你的数组
p *array@len
有时候你知道一段二进制代码所属的函数和偏移, 查这段对应的源代码:
list *myfunc+0x16

改变一个变量a的值为10
set variable a=10

7 查看内存

用命令"x /nfu <addr>"
n表示要显示的内存单元的个数
f表示显示方式, 可取如下值
x 按十六进制格式显示变量。
d 按十进制格式显示变量。
u 按十进制格式显示无符号整型。
o 按八进制格式显示变量。
t 按二进制格式显示变量。
a 按十六进制格式显示变量。
i 指令地址格式
c 按字符格式显示变量。
f 按浮点数格式显示变量。
u表示一个地址单元的长度
b表示单字节,
h表示双字节,
w表示四字节,
g表示八字节

8 其他


info source: 查看当前frame对应的源文件信息

(gdb) info source
Current source file is shared_ptr.hpp
Compilation directory is /usr/local/include/boost/smart_ptr
Located in /usr/local/include/boost/smart_ptr/shared_ptr.hpp
Contains 712 lines.
Source language is c++.
Compiled with unknown debugging format.
Does not include preprocessor macro info.
info threads: 查看当前线程数目以及状态

(gdb) info threads
       Id   Target Id         Frame
       3    process 35 thread 27  0x34e5 in sigpause ()
       2    process 35 thread 23  0x34e5 in sigpause ()
     * 1    process 35 thread 13  main (argc=1, argv=0x7ffffff8)
         at threadtest.c:68