Title Debugger Machine Asm Build Quick ref. author GPL(C) Mohsin Ahmed, http://www.cs.albany.edu/~mosh vim:ft=c: ========================================================================== section DEBUGGING tag debugging() char HEX[] = "0123456789abcdef"; #define printhex( c ) printf( "%c%c", HEX[ (c>>4)&0xF], HEX[c&0xF]) WORD to_hex( uchar c) { return ( HEX[ (c>>4)&0xff ] << 8) | // char 1. ( HEX[ c &0xff ] ); // char 2. } DEBUG_FILE_EXAMPLE { How to get rid of all printfs'?' #define printf (void) /* void all printf in a file */ How to selectively debug print'?' $ cat debug.h #define DEBUG_TYPE_A = 0x1 #define DEBUG_TYPE_B = 0x2 #define DEBUG_TYPE_C = 0x4 #define IF_DEBUG( WHAT ) if( DEBUG_TYPE_ ## WHAT & debugflags ) #define TRACE(WHAT,ARGS) IF_DEBUG( !(WHAT) );else{ printf ARGS; } extern int32 debugflags; // in debug.c $ cat main.c int32 debugflags = 0; ... debugflags = 0x3; // initialize in debugger. ... TRACE( A, ("ok argc=%d",argc)); // trace only if DEBUG_TYPE_A ... IF_DEBUG( B ){ breakpoint; } // breakpoint only if DEBUG_TYPE_B ... int checksum_date( void ) { // Unique compile time CHECKSUM from compiled date and time: int sum=0, k=4; int *p=(int*)__TIME__ __DATE__; while(k-->0) sum += *p++; return sum; } =========================================================================== section Calling_conventions tag calling() { /* +---------------------+------------------+ | params-order | stack | | forward reversed | cleanup | +---------+-----------+------------------+ | - | cdecl | caller (main) | | pascal | stdcall | callee (func) | +---------+-----------+------------------+ call naked vxd (no prologue,epilogue) fastcall params in register. - Only Pascal pushes params in forward order - left to right. - Params are pushed right to left (reversed) in stdcall and cdecl. - Callee cleans up params in stdcall. Eg. push param1 call Func .. Func: ... ; stdcall ret 04H ; callee cleaning up. - Caller cleans up cdecl, necessary for varargs eg printf, since only caller knows what to pop off. Eg. push param1 call printf ; cdecl function called add esp,04H ; caller cleaning +-------+ FFFF, Underflow. |-InUse-| |-STACK-| |-------| <- After x = pop, x = [sp++] |-------|<-SP | | <- After push x, [--sp] = x. | Empty | | | +-------+<-SS:0000 Overflow. callee_cdecl_frame( bp+8, bp+12, bp+16, bp+20, bp+24, ... ) // Param_i is at bp+4i+4. { prologue -- save sp, set bp, alloc locals on stack. int bp-4, bp-8, bp-12, bp-16, bp-20,....; // Local_i is at bp-4i, function body epilogue -- restore sp. return eax to caller in bp+4. } */ } Examples moshtag=cdecl_example. > cat cdecl.c int main(int argv, char * argv[] ) { cdecl_f(a,b,c); // push c, push b, push a, call cdecl_f() } _cdecl int cdecl_f( a, b, c ) { int d,e; // Local vars on stack. d = a+b+c; // See picture below to locate vars. return d; // result goes back in AX. } > cat cdecl.asm ; main(){ cdecl_f(1,2,3); } push c push b push a ; pushed in reverse order. call cdecl_f ; call add sp, 3*sizeof(int) ; clean up (pop off a,b,c). ; result in ax. ; int cdecl_f( a, b, c ){ int d,e ; d=a+b+c; return d; } } push bp ; Last old frame ptr. moshtag=prologue mov bp, sp ; Our new frame ptr. sub sp, sizeof(locals) ; Create d,e on stack. mov [bp-4], [bp+8] ; d := a add [bp-4], [bp+12] ; d += b add [bp-4], [bp+16] ; d += c mov ax, [bp-4] ; ax = d ; Ready to return result in AX. mov sp,bp ; Remove locals d,e. moshtag=epilogue pop bp ; Restore bp ret 0 ; pop ip = return. Stack when addition: d=a+b+c is executed in callee _cdecl add(): +-----------+ FFFF | | In Use | c | p3 (BP+16) Param 3 | b | p2 (BP+12) Param 2 | a | p1 (BP+8) Param 1 | Ret Addr | (BP+4) Return Address. | Old bp | <- BP Previous Frame ptr. | d | l1 (BP-4) Local 1 | e | l2 (BP-8) Local 2 | | <- SP Empty +-----------+ SS:0000 Stack: +-----------+ FFFF High Memory. |--Other----| (In Use) |- c 3------| p3 (BP+16) Param 3 |- b 2------| p2 (BP+12) Param 2 |- a 1------| p1 (BP+8) Param 1 |- ret addr-| |- old bp -| <- BP Frame ptr. |- d -------| l1 (BP-4) Local 1 |- e -------| l2 (BP-8) Local 2 |- -| <- SP (Empty) Grows downward, on push. |- -| +-----------+ SS:0000 Low Memory. ==================================================== Stack Fencing ; /GX zapping the stack in prologue ; moshtag=prologue_gx 55 push ebp 8B EC mov ebp,esp 83 EC 4C sub esp,4Ch ; make space for locals. 53 push ebx 56 push esi 57 push edi 8D 7D B4 lea edi,[ebp-4Ch] ; get address of locals. B9 13 00 00 00 mov ecx,13h ; size of locals to zap. B8 CC CC CC CC mov eax,0CCCCCCCCh ; value to zap with. F3 AB rep stos dword ptr [edi] ; zap as string on stack. ; /GX checking the stack ptr before return ; moshtag=epilogue_gx 5F pop edi 5E pop esi 5B pop ebx 83 C4 4C add esp,4Ch ; junk the locals. 3B EC cmp ebp,esp ; check esp is same as start. ; if equal, flag ZF will be ZR E8 60 6F 2F 00 call __chkesp ; In i386/chkesp.c 8B E5 mov esp,ebp ; restore real esp 5D pop ebp ; restore parent frame ptr. C3 ret ; go back to parent. ==================================================== moshtag=turbo,pascal pascal() { /* o Function must save bp, sp, ss, ds; rest ok to munge. o Return result in AX. o If Function is near, params start at bp+4, else bp+6 (far). o ret is far/near depending on func. o Params pushed in forward order, and cleaned by function. // Pascal Call: push Param1 push Param2 ... push ParamN (push bp) ; if Function is nested. call Function ; Function will pop off Param1..N // Function: ; Entry -- prologue push bp ; save previous stack frame. mov bp,sp sub sp,LocalSize ; allocate local vars on stack ..... ..... ; Exit -- epilogue move sp,bp ; restore old stack pop bp ; and bp ret ParamSize ; Remove Params and return (far or near). */ } section x86_ADDRESSING_MODES moshtag=addressing_modes,asm,assembly 1. Indirect addressing: mov ax, [si] ; si has the address. mov ax, es:[bx] 2. Indexing: mov ax, list[si] ; si and di are index regs. 3. Base register bx: lea bx, list mov ax, [bx][di] 4. Base + Displacement: mov ax, table[bx][di]; section x86_DisAssembly tag disassembly() { Do it yourself with: gcc -s cl /Fc cl /E (preprocess) msdev checkbox for assembly+listing. /* 1 IF THEN ELSE // if( x ) g() else h(); ??? 2 FOR // for( i = 100; i > 0; i-- ) f(); L1: mov cx, 100 call f loop L1 3 REPEAT UNTIL // for( i = 100; i>0 && c; i-- ) c = f(); L1: mov cx, 100 call f mov c, ax cmp ax,0 loopne L1 ;; what about i>0 test. 4 WHILE C DO // while( g > 0 ) f(); L1: cmp g, 0 JNG L2 call f sub g, 1 jmp L1: L2: 5 BYTE COPY // memcpy( dest, src, n ); lea di, dest lea si, src mov cx, n cld ; copy forward, ie ++, std will --. rep movsb ; while( cx-- != 0 ){ *di++ := *si++; } 6 BYTE COMPARE // memcmp( s1, s2, n) ; Compare n bytes s1[0..n-1] and s2[0..n-1], and ; return 0 if ==, +ve if s1>s2, -ve if s1project->settings->C/C++ -> Project-Options Remove /nologo to see cl.exe command line and flags used to build each exe. > dir /s/b msdev.exe cl.exe link.exe stdio.h libc*.lib .. Find the DIRS > PATH=... .. Set the dirs. > INCLUDE=... > LIB=... > cl /? .. Find the options. /ZI for debug, /GZ enables run time checks, ie: 1. Auto-init of local vars. 2. Function pointer call stack validation 3. Call stack validation /F20000000 .. Large stack for program. /LD .. make dll See cl /? and MSDN for details. > cl /W4 bogomips.c --> bogomips.obj --> bogomips.exe .. Max warning level. > cl /P bogomips.c --> bogomips.i .. Preproccesed file. > cl /Zg bogomips.c .. Shows func prototypes. > cl /FAs bogomips.c --> bogomips.asm .. Assmembler input. > cl /Fm bogomips.c --> bogomips.map .. Linked symbols loc and libraries. > cl /Fc bogomips.c --> bogomips.cod .. Machine code listing with asm. > dumpbin.exe /disasm bogomips.exe .. asm listing. > dumpbin.exe /imports bogomips.exe .. asm listing. > dumpbin /exports kernel32.dll .. functions exported. > link /dump /exports kernel32.dll .. See exports. > dumpbin /symbols bogomips.obj .. See what linker saw. > dumpbin /headers bogomips.exe > dumpbin /headers c:/winnt/system32/KERNEL32.DLL | grep base 77F00000 image base .. Where it will be loaded in your process. > bind -vu bogomips.exe .. Edit bogomips.exe and insert dll:func addresses Otherwise fixups occur at startup time. > ctags --c-types=px *.c .. Find externs that belong in header file. > ctags -? .. For other --c-types options. ========================================================== Ms.Dev turn on the debugger -- sung by Rainbow! VC->Project->settings Select settings for Exe=[pick lib or exe] Select Config=[pick Debug,Retail,etc] 1 Tab C/C++: set Debug-Info=[Program Database] (/Zi in program options). =[Program Database for edit and continue] (/ZI). 2 Tab Link: set [X] generate debug info (/debug to linker). 3 C/C++ program option type "/GX" to fence stack, /O2 for maximize speed. ========================================================== Preprocess: moshtag=preprocess > cl /P file.c .. to file.i > cl /E file.c .. to stdout > gcc -E file.c Generate Make Dependencies: > gcc -M file.c file.o: file.c > gcc -MM main.c .. Skip system includes from dep. > make -W file.c .. Compile file.c even if upto date Protoypes: moshtag=prototypes M-x c-prototypes hp> protogen vc> cl /Zg > cl /ZI /Zg /Od /Op /FD /c \ /Fo"${TMP:=/tmp}" /Fd"$TMP" \ /GZ @${SRC:?}/def.txt /GZ @$SRC/inc.txt \ *.c > protos.1 perl -pe 's,__cdecl\s+,,; s,(^.*?\s)(\w+)\(,\2: \1\2(,;' protos.1 | \ sort |uniq > protos.2 > ctags --c-types=px --file-scope=no *.c > externs-in-c.txt > ctags -x -R . > ptype.txt; ctags -x --c-types=px -R . >> ptype.txt > ctags -x --c-types=px -R . > protos.txt > ctags --file-tags=yes -R . # writes ./tags > ctags --file-tags=yes -R . -o etags -e # writes ./etags ========================================================== moshtag=compilation > cl kernel32.lib advapi.lib gdi32.lib user32.lib *.c # moshtag=win32libs > cl /Ox /W kernel32.lib bogomips.c ; bogomips.exe # win32: > cl /Ox /W kernel32.lib bogomips.c ; bogomips.exe # win64?:; > gcc -O2 bogomips.c ; ./a.out # linux: > cc -O +DA1.1 +DS2.0 bogomips.c ; ./a.out # hp11: > cc -O +DA2.0W +M2 bogomips.c ; ./a.out # hp1164: > cc -xO5 bogomips.c ; ./a.out # solaris: > cc -xO5 -xarch=v9 -D__LP64__ bogomips.c ;./a.out # solaris64: > tcc -G -O -M -a -S -f87 -mh -w -Iinclude -Llib bogomips.c ========================================================== Debugging moshtag=debugging - msdev - nt/95 gui - windbg - nt/95 gui + cmdline + kernel debugger client. - ntsd - nt cmdline, user mode. - cdb - 95 cmdline, user mode. Warning: Both ntsd and cdb are buggy on my NT, so use windbg or vc only - i386kd - NT kernel debugger, server over COM1. - wdeb386 -- win9x kernel debugger, server over COM1. - softice -- NT/95 kernel debugger. - wdb/gdb -- HP, gui + cmdline. - workshop/dbx -- Sun solaris, gui + cmdline. - adb/sdb -- Unix cmdline - emacs+gdb+gud(~/emacs/mosh-gdb.el) -- gui frontend to gdb,dbx,.. - perl -D Most useful commands are bound to unshifted keys in msdev,emacs+gud,xterm or gdb,dbx,wdb aliases. Important Commands Mnemonics and vc keys. - A-F7 set args - F5 run, continue - F10 next line - F11 step in - F12 step out, finish - F2 goto, jump - F6 until - bt backtrace - bp breakpoint - frame up/down - print - stop/Break - q quit ===================================================== Controlling MsDev from Perl Ole script moshtag=send-to-msdev More help in msdn or internet, search for "MSDev.Application". See $VC/include/objmodel/textdefs.h for dsMatchWord used in FINDTEXT. > cat send-to-msdev.pl USAGE="Usage: send2msdev.pl VIEWFILE [GOTOLINE_OR_FINDTEXT]"; Get $VIEWFILE $GOTOLINE $FINDTEXT or $ARGS or die $USAGE; push(@INC,"d:/perl/perl_55x/lib/site"); # Only ActiveX Perl OLE works. require Win32::OLE; $app = Win32::OLE->GetActiveObject("MSDev.Application"); $app = Win32::OLE->new("MSDEV.APPLICATION") if ! defined $app; die "Cant open MsDev.\n" unless $app; $app->{"WindowState"} = 1 if $app->{"WindowState"} == 2; $app->{"Visible"}=1; $app->{"Active"}=1; $file = $app->{"Documents"}->Open("$VIEWFILE"); die "Cant Open File=$VIEWFILE in MsDev.\n" unless $file; print( $app->FullName()," ",$file->FullName()," type=",$file->Type(),".\n" ); print("PWD=",$app->CurrentDirectory(),".\n"); $file->Selection()->GotoLine($GOTOLINE) if $GOTOLINE; $file->Selection()->FindText($FINDTEXT},2) if $FINDTEXT; $file->Selection()->Selectline(); # highlight it. =========================================================== moshtag=xterm_debugger ~/.Xdefaults XTerm*vt100.translations: #override\n\ F9: string("!!\n") \n\ F10: string("next\n") \n\ F11: string("step\n") \n\ C-F11: string("stepi\n") \n\ F12: string("finish\n") \n\ =========================================================== moshtag=msdev MSDEV Data Breakpoints moshtag=data_breakpoint -> Edit -> Breakpoints -> -> Breakpoint Menu -> Data -> *(int*)0x123456 and length=1 (Stop when data changes). Where 0x123456 is &corrupt_var Caveat: Pointer must be in process mem space, otherwise bp cannot be set, so run till mem is allocated, Guess when to to stop and try to enable the bp. Win32 API List See $MsDev/lib/win32api.csv vc watch Auto Expander e:/vc6/msdev98/bin/AutoExp.dat $MSDEV/msdev98/bin/autoexp.dat [ExecutionControl] func=NoStepInto vc internal variables to watch: @err,hr .. GetLastError @clk .. ms Time since last debug stmt. @clk=0 .. reset timer. Win9x reg FS See SetThreadName NT @tib+24 Thread info Block bp {,,dllname}function bp {[function],[sourcefile],[exe]}'location|variable|expression' {,,msvcrtd.dll}.crtDebugFlag=5 .. To set a Dll var. {,,kernel32.dll}CreateProcessA@40 .. See exact name with dump. VC JIT Just-in-Time debugging Registry settings: moshtag=jit \\HKLM\Software\Microsoft\Windows NT\CurrentVersion\AeDebug\ 1. Debugger=debugger_name, eg. Debugger = "NTSD -p %ld -e %ld -g" 2. Auto=1, or 0 to ask to debug on crash. Memory map VC: vc->debug->modules (and GetProcAddress,pstat.exe,ntps.exe) Solaris: /usr/proc/bin/pmap PID Linux: gtop OpCodes to use in edit memory at EIP: 0x90 NOP 0x74 JE 0x75 JNE __asm int 3 ; // Inline assembly to launch debugger. Hbreak from code: int z=0; __asm { mov eax,offset z mov dr7,ax // doesn't work, error: privileged intruction. } z++; VC Compile time Assertion: Eg. #define compiler_assert(expr) typedef char __COMPILER_ASSERT__[(expr)?OK:-ERR] compiler_assert(sizeof(i)==4); int j; int i = (int) &j; =========================================================== NT Command line debugger: moshtag=quick_ntsd > ntsd /? .. Options help ? .. Help ~ .. Threads G .. Go (wdeb g) P .. Next T .. Step K,KB,KD, .. Stack dumps. LN .. List near symbols. ~*KB .. Thread Stacks U .. Disassemble BP,BC,BD,BE,BL .. Break,Clear,Disable,Enable,List. X * .. Show symbols. D .. Dump Mem Q .. Quit > ntsd $PWD/bogomips.exe .. ntsd need abs path. ----------------------------------------- Win9x Debuggers: moshtag=cdb cdb uses same console window - so can use previous history. > cl /GZ /ZI /MLd bogomips.c .. Compile max debug. > windbg bogomips.exe .. moshtag=windbg windbg> BP main windbg> BP main "j ...." .. Dont use '' for conditional bp. windbg> DW count count+1 .. Print variable int count. windbg> dw ss:ebp+8 ss:ebp+9 .. Print arg1 from stack, (after prologue). windbg> db str .. print variable char *str? windbg> G .. go, break in main windbg> LN .. list near windbg> KB .. show stack windbg> KD .. show raw stack windbg> X * .. Find all symbols in program. windbg> D 12 .. Dump some mem windbg> U .. Disassemble windbg> P .. Next windbg> R .. Registers windbg> T .. Step into windbg> Q .. Quit Examples: windbg> bp exit; g; windbg> ? [ss:esp]4 .. See arg1 to exit. windbg> dw ss:esp+3 ss:esp+4 .. Same. BP syntax: set using menu, and open menu again to see the equivalent cmdline syntax. windbg> bp main =i /R1 /H0 .. In main, stop if 'i' is modified, (gdb hbreak). windbg> bl .. bl=list, bc=clear, bd=disable, be=enable. > disasm eip Eg. func: sub esp,8h ; func creating space for 2 int local vars on stack. Eg. mov eax,dword ptr [ebp+8h] ; Accessing 2nd param (positive offset). Eg. mov eax,dword ptr [ebp-8h] ; Accessing 2nd local var (negative offset). =========================================================== moshtag=wdeb386 wdeb386 prompts See msdn for more. > or >> .. Real mode (boot time) # or ## .. Protected mode - or -- .. V86 (virtual 8086 mode) - .dosmgr .. stack, list near # .R .. Registers, check CS reg value CS_reg mod 4 == RING. VXD EIP is of type 0xCxxxxxxx, while win32 app EIP is in 0x00400000-0xBFFFFFFF. ---- ----------------- CS CODE AREA ---- ----------------- 0028 VxD code (ring 0) 0030 VxD data (ring 0) 013F Win32 flat code 0147 Win32 flat data 0048 debugger code 011F Krnl386 code 0137 Krnl386 data ---- ----------------- =========================================================== moshtag=dbx $ cc -S f.c .. make f.S assembly of f.c $ cc -g f.c .. make a.out $ dbx .. debug it now. sourcing ~/.dbxrc .. (gdb ~/.gdbinit) (vc->tools->options). (dbx) debug a.out .. Set exe (vc project->settings) (dbx) help .. (alias h) (vc help,msdn) (info gdb). (man dbx,sun answerbook,norbye tutorial). (dbx) runargs arg1 arg2 .. (gdb set args) (vc project->settings). (dbx) pathmap DIR .. Set path to src, (dbx) run .. S-F5 (alias r) (dbx) whatis argc .. Find type of argc (alias pt) (dbx) print .. F8 (vc debug->quick watch) (dbx) print argv[0..5] .. Print array. (vc quick watch=argv,5). (dbx) when in malloc { print $i0 } .. Print unnamed args. (dbx) file .. was-F2 Where in src are we. (vc->debug->show next stmt) (dbx) list .. Show source f.c at $lineno (alias l). (dbx) edit .. Edit f.c (alias v) (dbx) regs .. A-5 Registers (gdb i reg) (vc view->debug->reg) (dbx) x .. A-6 Examine Memory (vc view->debug->mem) (dbx) disas $pc .. A-8 Disassemble (vc: C-F11 also)(ntsd: u) (dbx) next .. F10 (alias n) (dbx) step .. F11 (alias s) (dbx) stepi .. C-F11 Step intruction (alias i) (dbx) !! .. Redo (gdb [C-M]). (dbx) where .. A-7 Backtrace (alias bt) (ntsd: kb) (dbx) up .. To to caller frame. (alias u) (vc click stack) (dbx) dump .. A-4 Print local vars (vc view->debug->vars) (dbx) down .. Goto Callee Frame. (alias d) (vc click stack). (dbx) finish .. F12 Complete function and return. (dbx) stop main.c:15 -temp;cont .. F13 Run to line (gdb until) was 'cont to'. (dbx) cont at main.c:15 .. F2 Set cursor ($pc) to line (gdb jump). (dbx) cont .. F5 Continue from breakpoint, (alias c) (ksh) continue .. ksh command != cont. (dbx) pop .. F15 (gdb return from cursor) (dbx) stop at main.c:15 .. F9 .. breakpoint. (alias b) (dbx) stop ACCESS VAR .. A-F9 Data breakpoint (vc edit->breakpoint->data). .. gdb: hbreak, ntsd: ba w4 %addr, wdeb: br w4 %addr .. check. (dbx) stop in exit -if $o0 != 0 .. A-F9 break on abnormal exit. .. (windbg: bp exit 'j((ss:esp+4)!=0) r;g' -- check) (dbx) status .. A-F9 List stoppers (breakpoints etc) (alias stops). (ntsd: bl) (dbx) delete 3 .. A-F9 Remove breakpoint 3. (dbx) trace main .. Report when and who callers are. (dbx) display i .. A-3 Watch i. (dbx) display ; undisplay 1 .. A-3 List watches, remove watch 1. (dbx) quit .. (alias q) (dbx) alias l='ls -l' .. (gdb 'define l\n shell ls\n end') .. (vc->tools->customize->tools->ls ) =========================================================== moshtag=gdb $ gcc -S f.c .. make f.S assembly of f.c $ gcc -g f.c .. make a.out $ gdb .. debug it now. sourcing ~/.gdbinit (gdb) directory DIR .. dir containing source. (gdb) cd DIR (gdb) file a.out .. set exe (dbx debug a.out) (gdb) set args arg1 arg2 .. (dbx runargs arg1 arg2) (gdb) break main .. F9 (dbx stop in main) (gdb) run .. S-F5 (dbx run) (gdb) next .. F10 (dbx next) (gdb) step .. F11 (dbx step) (gdb) stepi .. C-F11 (dbx stepi) (gdb) until line .. F13 Out of loop (use temp bp in dbx). (gdb) return expr .. F15 Return from cursor. (dbx pop). (gdb) finish .. F12 Complete function. (dbx finish). (gdb) continue .. F5 (dbx cont, NOT continue) (gdb) jump [lineno|*addr] .. F2, Set cursor to line. (dbx 'cont at') (gdb) set $pc = 0x123 .. A-F8, watch. (gdb) print x = 1 .. F8, set and print x. (gdb) whatis .. Print type of x. (gdb) ptype x (gdb) info type regexp (gdb) info scope main .. List vars in main .. see 'info gdb in emacs' (gdb) info symbol 0x222 .. x .. Loc of x is 0x222 (gdb) i b (info break) .. List stops (dbx status) (ntsd: bl). (gdb) b free commands \n return \n end .. (dbx: when in free {pop;}) .. (wdeb386,ntsd,cdb,i386kd: bp free commands) .. (vc:none, but see advanced bp menu) (gdb) print /x x .. Print x in hex. (gdb) print/t x .. Print x in base two/binary. (gdb) break *0x222 .. A-F9 data breakpoint. (gdb) rbreak .*init.* .. Stop on all init funcs (gdb) trace f.c:121 .. Print message when executing this line. (gdb) trace +2 .. 2 lines forward (gdb) trace init .. First source line of function (gdb) trace *init .. Trace at exact start of function (gdb) trace *0x123456 .. Trace an address (gdb) delete trace 5 .. Remove tracepoint 5. (gdb) print *argv@5 .. Print array (gdb) delete trace .. (gdb) quit .. (dbx quit). =========================================================== Emacs Elisp Debugger backtrace: moshtag=edebug Also see elisp.info M-x edebug (setq debug-on-error t ) (setq debug-on-error nil) (cancel-debug-on-entry) M-x debug-on-entry M-x cancel-debug-on-entry M-x toggle-debug-on-error M-C-] To end recursive edit. Edebugger: h: F1 help b: F9 set bp (*). u: F9 unset clear bp d: F11 step into bc:\F6 step to cursor j: \F2 jump l: bl list breakpoints. c: F5 continue e: \F8 Eval expr R: Eval expr in *Debugger-record* r: return value. q: quit ============================================================