\msection{Debugging}{Ali Saidi\\[1cm] \small{ARM Research \& Development}}
\begin{frame}
\frametitle{Debugging Facilities}
   \bi 
   \setlength\itemsep{\fill}
   \item Tracing
      \bi
      \item Instruction Tracing
      \item Diffing Traces
      \ei
   \item Using the gdb to debug gem5
      \bi
      \item Debugging \CC and gdb-callable functions
      \item Remote Debugging
      \ei
   \item Python Debugging
   \item Pipeline Viewer
   \ei
\end{frame}

\begin{frame}
\frametitle{Tracing/Debugging \hfill \textbt{\footnotesize{src/base/trace.*}}}
   \bi 
   \setlength\itemsep{\fill}
   \item \texttt{printf()} is a nice debugging tool
   \item Keep good printfs for tracing
   \item Lots of debug output is a very good thing
   \item Example flags:
      \bi 
       \item Fetch, Decode, Ethernet, Exec, TLB, DMA, Bus, Cache, Loader, O3CPUAll, etc.
      \ei
   \item Print out all flags with \small{\texttt{-{}-debug-help}} option
   \ei
\end{frame}

\begin{frame}
\frametitle{Enabling Tracing}
\bi
    \item Selecting flags:
    \bi
        \item \small{\texttt{-{}-debug-flags=Cache,Bus}}
        \item \small{\texttt{-{}-debug-flags=Exec,-ExecTicks}}
    \ei
    \item Selecting destination:
    \bi
        \item \small{\texttt{-{}-trace-file=my\_trace.out}}
        \item \small{\texttt{-{}-trace-file=my\_trace.out.gz}}
    \ei
    \item Selecting start:
    \bi
        \item \small{\texttt{-{}-trace-start=23000000}}
    \ei
    \vfill
    \small{\texttt{./build/ARM\_FS/gem5.opt --debug-flags=Cache,Bus --trace-start=2400 configs/example/fs.py}}
\ei
\end{frame}

\begin{frame}
\frametitle{Adding Tracing}
\bi
    \item Print statement put in source code
    \bi
        \item Encourage you to add ones to your models or contribute ones you find particularly useful
    \ei
    \item Macros remove them for gem5.fast or gem5.prof binaries
    \bi
        \item So you must be using gem5.debug or gem5.opt to get any output
    \ei
    \item Adding an extra tracing statement:
    \bi
        \item \small{\texttt{DPRINTF(Flag, ``normal printf \%s$\backslash$n'', ``arguments'');}}
    \ei
    \item Adding a new trace flags (in a SConscript):
    \bi
        \item \small{\texttt{DebugFlag('MyNewTraceFlag')}}
    \ei
\ei
\end{frame}
 
\begin{frame}[fragile,shrink]
\frametitle{Instruction Tracing \hfill \textbt{\footnotesize{src/sim/insttracer.hh}}}
    \bi
    \item Separate from the general debug/trace facility
    \bi
        \item But both are enabled the same way
    \ei
    \item Per-instruction records populated as instruction executes
        \bi
        \item Start with PC and mnemonic
        \item Add argument and result values as they become known
        \ei
    \item Printed to trace when instruction completes
    \item Flags for printing cycle, symbolic addresses, etc.
   \ei
\begin{indverb}{\textwidth}{0cm}{\textwidth}
\begin{verbatim}
4000: sys.cpu : @sym+776   : add  r3, r3, #8        : IntAlu  : D=0x00008358
4500: sys.cpu : @sym+780   : sub  r3, r3, r7        : IntAlu  : D=0x40000000
5000: sys.cpu : @sym+784   : add  r5, r5, r3        : IntAlu  : D=0x000173cc
5500: sys.cpu : @sym+788   : add  r6, r6, r3        : IntAlu  : D=0x00017400
6000: sys.cpu : @sym+792.0 : addi_uop  r34, r5, #0  : IntAlu  : D=0x000173cc
6500: sys.cpu : @sym+792.1 : ldr_uop  r3, [r34, #0] : MemRead : D=0x000f0000 A=0x173cc
7000: sys.cpu : @sym+792.2 : ldr_uop  r4, [r34, #4] : MemRead : D=0x000f0000 A=0x173d0
7500: sys.cpu : @sym+796   : and  r4, r4, r9        : IntAlu  : D=0x000f0000
8000: sys.cpu : @sym+800   : teqs  r3, r4           : IntAlu  : D=0x00000001
\end{verbatim}
\end{indverb}
\end{frame}


\begin{frame}[fragile]
\frametitle{Using GDB with gem5}
    \bi
    \item Several gem5 functions designed to be called from GDB:
        \bi
        \item \textbt{schedBreakCycle()} -- also with \texttt{-{}-debug-break}
        \item \textbt{setDebugFlag()}/\textbt{clearDebugFlag()}
        \item \textbt{dumpDebugStatus()}
        \item \textbt{eventqDump()}
        \item \textbt{SimObject::find()}
        \item \textbt{takeCheckpoint()}
        \ei
    \ei
\end{frame}


\begin{frame}[fragile]
\frametitle{Using GDB with gem5}
\begin{indverb}{\textwidth}{0cm}{\textwidth}
\begin{verbatim}
gdb --args ./build/ARM_FS/gem5.opt configs/example/fs.py 
GNU gdb Fedora (6.8-37.el5)
...
(gdb) b main
Breakpoint 1 at 0x4090b0: file build/ARM_FS/sim/main.cc, line 40.
(gdb) run
Breakpoint 1, main (argc=2, argv=0x7fffa59725f8) at build/ARM_FS/sim/main.cc:40
    40main(int argc, char **argv)
(gdb) call schedBreakCycle(1000000)
(gdb) continue
Continuing.
gem5 Simulator System
...
0: system.remote_gdb.listener: listening for remote gdb #0 on port 7000
**** REAL SIMULATION ****
info: Entering event queue @ 0.  Starting simulation...

Program received signal SIGTRAP, Trace/breakpoint trap.
0x0000003ccb6306f7 in kill () from /lib64/libc.so.6
(gdb) p _curTick
$1 = 1000000
\end{verbatim}
\end{indverb}
\end{frame}

\begin{frame}[fragile]
\frametitle{Using GDB with gem5}
\begin{indverb}{\textwidth}{0cm}{\textwidth}
\begin{verbatim}
(gdb) call setDebugFlag("Exec")
(gdb) call schedBreakCycle(1001000)
(gdb) continue
Continuing.
1000000: system.cpu T0 : @_stext+148. 1 :   addi_uop   r0, r0, #4 : IntAlu : D=0x0000000000004c30
1000500: system.cpu T0 : @_stext+152    :   teqs   r0, r6         : IntAlu : D=0x0000000000000000

Program received signal SIGTRAP, Trace/breakpoint trap.
0x0000003ccb6306f7 in kill () from /lib64/libc.so.6
(gdb) print SimObject::find("system.cpu") 
$2 = (SimObject *) 0x19cba130
(gdb) print (BaseCPU*)SimObject::find("system.cpu")
$3 = (BaseCPU *) 0x19cba130
(gdb) p $3->instCnt
$4 = 431
(gdb) call clearDebugFlag("Exec")
(gdb) call takeCheckpoint(0)
(gdb) call schedBreakCycle(1001500)
(gdb) continue
Continuing.
Writing checkpoint
info: Entering event queue @ 1001001.  Starting simulation...

Program received signal SIGTRAP, Trace/breakpoint trap.
0x0000003ccb6306f7 in kill () from /lib64/libc.so.6
(gdb) 
 
\end{verbatim}
\end{indverb}
\end{frame}

\begin{frame}
\frametitle{Diffing Traces \hfill \textbt{\footnotesize{util/\{rundiff,tracediff\}}}}
    \bi
    \item Often useful to compare traces from two simulations
        \bi
        \item Find where known good and modified simulators diverge
        \ei
    \item Standard {\em diff} works only on files (not pipes)
        \bi
        \item ...but you really don't want to run to completion
        \ei
    \item \textbt{util/rundiff}
        \bi
        \item Perl script for diffing two pipes on the fly
        \ei
    \item \textbt{util/tracediff}
        \bi
        \item Handy wrapper for using \textbt{rundiff} to compare gem5 outputs
        \item {\footnotesize\textbt{tracediff "a/gem5.opt|b/gem5.opt"
{-}-debug-flags=Exec}} compares instruction traces from two builds of gem5
        \item See comments for details
        \ei
   \ei
\end{frame}


\begin{frame}
\frametitle{Advanced Trace Diffing}
\bi
    \item Sometimes if you run into a nasty bug it's hard to compare apples-to-apples traces 
    \item Different cycle counts, different code paths from interrupts/timers
    \item Some mechanisms that can help:
    \bi
        \item \small{\texttt{-ExecTicks}} don't print out ticks
        \item \small{\texttt{-ExecKernel}} don't print out kernel code
        \item \small{\texttt{-ExecUser}} don't print out user code
        \item \small{\texttt{ExecAsid}} print out ASID of currently running process
    \ei
    \item State trace
    \bi
        \item PTRACE program that runs binary on real system compares cycle-by-cycle to gem5
        \item Supports ARM, x86, SPARC (and support is best in that order)
        \item See wiki for more information
    \ei
\ei
\end{frame}

\begin{frame}[fragile,shrink]
\frametitle{Remote Debugging}
\begin{indverb}{\textwidth}{0cm}{\textwidth}
\begin{verbatim}
./build/ARM_FS/gem5.opt configs/example/fs.py 
gem5 Simulator System

...
command line: ./build/ARM_FS/gem5.opt configs/example/fs.py
Global frequency set at 1000000000000 ticks per second
info: kernel located at: /chips/pd/randd/dist/binaries/vmlinux.arm
Listening for system connection on port 5900
Listening for system connection on port 3456
0: system.remote_gdb.listener: listening for remote gdb #0 on port 7000
info: Entering event queue @ 0.  Starting simulation...

\end{verbatim}
\end{indverb}
\end{frame}

\begin{frame}[fragile,shrink]
\frametitle{Remote Debugging}
\begin{indverb}{\textwidth}{0cm}{\textwidth}
\begin{verbatim}
GNU gdb (Sourcery G++ Lite 2010.09-50) 7.2.50.20100908-cvs
Copyright (C) 2010 Free Software Foundation, Inc.
...
(gdb) symbol-file /dist/binaries/vmlinux.arm
Reading symbols from //dist/binaries/vmlinux.arm...done.
(gdb) set remote Z-packet on
(gdb) set tdesc filename arm-with-neon.xml
(gdb) target remote 127.0.0.1:7000
Remote debugging using 127.0.0.1:7000
cache_init_objs (cachep=0xc7c00240, flags=3351249472) at mm/slab.c:2658
(gdb) step
sighand_ctor (data=0xc7ead060) at kernel/fork.c:1467
(gdb) info registers
    r0             0xc7ead060-940912544
    r1             0x5201312
    r2             0xc002f1e4-1073548828
    r3             0xc7ead060-940912544
    r4             0x00
    r5             0xc7ead020-940912608
    r6             0x00
    r7             0xc7ead03c-940912580
    r8             0xc7c034a0-943704928
    r9             0x1001001048832
    r10            0xc7c0cee0-943665440
    r11            0x2002002097664
    r12            0xc0000000-1073741824
    sp             0xc7c29e280xc7c29e28
    lr             0xc008ed98-1073156712
    pc             0xc002f1e40xc002f1e4 <sighand_ctor>
    cpsr           0x1319
\end{verbatim}
\end{indverb}
\end{frame}

\begin{frame}[fragile,shrink]
\frametitle{Python Debugging}
\bi
    \item It is possible to drop into the python interpreter (\texttt{-i} flag)
    \bi
        \item This currently happens after the script file is run
        \item If you want to do this before objects are instantiated, remove them from script
    \ei
    \item It is possible to drop into the python debugger (\texttt{{-}-pdb} flag)
    \bi
        \item Occurs just before your script is invoked
        \item Lets you use the debugger to debug your script code
    \ei
    \item Code that enables this stuff is in src/python/m5/main.py
        \bi 
        \item At the bottom of the main function  
        \item Can copy the mechanism directly into your scripts, if in the wrong
place for you needs
        \item \small{\texttt{import pdb}}
        \item \small{\texttt{pdb.set\_trace()}}
        \ei 
\ei
\end{frame}

\begin{frame}[fragile,shrink]
\frametitle{O3 Pipeline Viewer}
Use \small{\texttt{-{}-debug-flags=O3PipeView}} and
\small{\texttt{util/o3-pipeview.py}} \\[.25cm]
\includegraphics<1>[scale=0.35]{images/o3pipeview.png}
\end{frame}



