\documentclass{beamer}
\usetheme{linutronix}
\usepackage{german}
\usepackage[utf8]{inputenc}
\usepackage{pgf}
\usepackage{graphicx}
\usepackage{lxextras}


\title{Block \lq Debugging\rq}
\institute{Linutronix GmbH}

\lstset{keywordstyle=\color{blue},commentstyle=\color{orange}}

\begin{document}

\maketitle
\begin{frame}
\frametitle{Übersicht}
\tableofcontents
\end{frame}

\section{Einfache Debugging Werkzeuge}
\subsection{Systemcalls tracen mit STRACE}
\begin{frame}
\frametitle{STRACE}
\begin{alertblock}{Was ist STRACE?}
STRACE ist ein mächtiges Diagnosewerkzeug, mit dem sich System Calls und Signale
tracen lassen.
\end{alertblock}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{Anwendungsbeispiel}
\begin{lstlisting}[language=bash,basicstyle=\ttfamily\fontsize{9}{9}\selectfont]
$ strace /bin/ls
execve("/bin/ls", ["/bin/ls"], [/* 38 vars */]) = 0
brk(0)                                  = 0x8061000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MA
0xb7f03000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=113431, ...}
[...]
\end{lstlisting}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{Wichtige STRACE Optionen}
\begin{itemize}
\item \textbf{-f}: Follow Forks
\item \textbf{-v}: Verbose mode
\item \textbf{-T}: Print out time which is spent in each syscall
\item \textbf{-p PID}: Attach to PID
\end{itemize}
\end{frame}

\section{Der GNU Debugger: GDB}
\subsection{Interaktives Debugging mit GDB}
\begin{frame}[containsverbatim]
\frametitle{Hello world debuggen}
\begin{enumerate}
\item Übersetzen mit Debug Informationen
\item Starten im Debugger:
\begin{lstlisting}[language=bash]
gdb ./hello
\end{lstlisting}
\end{enumerate}
\end{frame}


\begin{frame}[containsverbatim]
\frametitle{Wichtige GDB Kommandos}
\begin{verbatim}
(gdb) run
Starting program: /home/jan/work/examples/hello 
Hello world

Program exited normally.
(gdb)
\end{verbatim}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{Wichtige GDB Kommandos}
\begin{verbatim}
(gdb) list
1	#include <stdio.h>
2	
3	int main (void)
4	{
5		printf("Hello world\n");
6		return 0;
7	}
(gdb) break 5
Breakpoint 1 at 0x400528: file hello.c, line 5.
\end{verbatim}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{Wichtige GDB Kommandos}
\begin{verbatim}
(gdb) run
Starting program: /home/jan/work/examples/hello 

Breakpoint 1, main () at hello.c:5
5		printf("Hello world\n");
(gdb) next
Hello world
6		return 0;
(gdb) continue 
Continuing.
\end{verbatim}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{GDB Kommandos: Übersicht}
\begin{tabular}{|c|c|p{5cm}|}
\hline
\textbf{Kommando} & \textbf{Abkürzung} & \textbf{Zweck} \\
\hline
run & r & Programm starten \\
\hline
continue & c & Programm fortsetzen \\
\hline
break X & b & Breakpoint in Zeile X setzen \\
\hline
step & s & step IN \\
\hline
next & n & step OVER \\
\hline
print var & -- & Inhalt von Variable var anzeigen \\
\hline
display var & -- & Inhalt von Variable var jedes mal anzeigen, wenn das Programm stoppt \\
\hline
\end{tabular}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{GDB Kommandos: Übersicht}
\begin{tabular}{|c|c|p{5cm}|}
\hline
\textbf{Kommando} & \textbf{Abkürzung} & \textbf{Zweck} \\
\hline
backtrace & bt & Backtrace anzeigen \\
\hline
frame X & f & Im aktuellen Stack zu Frame Nr. X wechseln \\
\hline
quit & q & GDB beenden \\
\hline
\end{tabular}
\end{frame}

\subsection{Post mortem Analyse mit GDB}
\begin{frame}[containsverbatim]
\frametitle{Post Mortem Debugging mit GDB}
\begin{lstlisting}[language=C]
#include <stdio.h>

int main (void)
{
char *arthur_dent = NULL;
printf("Hello segfault world\n", *arthur_dent);
return 0;
}
\end{lstlisting}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{Post Mortem Debugging mit GDB}
\begin{lstlisting}[language=bash]
ulimit -c unlimited
$ ./hello_segfault 
Segmentation fault (core dumped)
$ ls -l core*
\end{lstlisting}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{Post Mortem Debugging mit GDB}
\begin{lstlisting}[language=bash,basicstyle=\ttfamily\fontsize{9}{9}\selectfont]
$ gdb hello_segfault core
[...]
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Core was generated by `./hello_segfault'.
Program terminated with signal 11, Segmentation fault.
#0  0x0000000000400538 in main () at hello_crash.c:6
6		printf("Hello segfaulting world\n",
				*arthur_dent);
(gdb) bt
#0  0x0000000000400538 in main () at hello_crash.c:6
\end{lstlisting}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{Wichtig Kommandos für Post Mortem Debugging}
\begin{tabular}{|p{5.5cm}|p{5cm}|}
\hline
\textbf{Kommando} & \textbf{Zweck} \\
\hline
ulimit & Coredumps aktivieren und größe festlegen \\
\hline
cat /proc/sys/kernel/core\_pattern & Aktuelles Namenspattern für core-Files anzeigen \\
\hline
echo core-\%p \textgreater /proc/sys/kernel/core\_pattern & Namenspattern für
core-Files setzen \\
\hline
gdb ./exe corefile & Coredump mit GDB anzeigen \\
\hline
\end{tabular}
\end{frame}

\subsection{Remote Debugging mit GDB}
\begin{frame}
\frametitle{Remote Debugging}
\begin{figure}[h]
\centering
\includegraphics[width=8cm]{images/remote_debug.png}
\end{figure}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{Remote Debugging session}
\begin{lstlisting}[language=bash]
$ powerpc-linux-gnu-gdb cross_hello
(gdb) set solib-absolute-prefix /XXX/libc/
(gdb) target remote 10.0.0.3:54321
Remote debugging using localhost:54321
0x30016180 in _start() from /XXX/libc/lib/ld.so.1
(gdb) c
\end{lstlisting}
Auf dem Target:
\begin{lstlisting}[language=bash]
$ gdbserver 10.0.0.2:54321 ./cross_hello 
Process ./cross_hello created; pid = 310
Listening on port 54321
Remote debugging from host 10.0.2.2
Hello world
\end{lstlisting}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{gdbinit}
GDB Kommandos automatisch ausführen:
\begin{lstlisting}[language=bash]
vim gdbinit.txt
\end{lstlisting}
\begin{verbatim}
set solib-absolute-prefix /XXX/libc/
target remote 10.0.0.3:54321
\end{verbatim}
\begin{lstlisting}[language=bash]
powerpc-linux-gnu-gdb -x gdbinit.txt cross_hello 
\end{lstlisting}
\end{frame}
\section{Memory debugging}
\begin{frame}
\frametitle{Memory debugging}
Gängige Probleme:
\begin{itemize}
\item Schreiben / Lesen über die Grenze von Speicherbereichen
\item Memory leaks
\item ''Use after free()''
\end{itemize}
\end{frame}
\subsection{MTrace}
\begin{frame}[containsverbatim]
\frametitle{GLIBC eigene Mechanismen: MTrace}
\begin{lstlisting}[language=C]
/* mem_test.c */
[...]
#include <mcheck.h>
[...]
int main(void)
{
   mtrace();
   [...]
}
\end{lstlisting}
\begin{lstlisting}[language=bash]
$ gcc -o mem_test mem_test.c
$ MALLOC_TRACE=mytrace.log ./mem_test
$ mtrace mem_test mytrace.log
\end{lstlisting}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{GLIBC eigene Mechanismen: MTrace}
\begin{lstlisting}[language=C,basicstyle=\ttfamily\fontsize{9}{9}\selectfont]
/* mem_leak.c */
#include <mcheck.h>
#include <malloc.h>
#include <stdio.h>

int main(void)
{
        int i = 0;
        char *blurb = NULL;

        mtrace();

        for(i = 0; i < 50; i++)
                blurb = malloc(sizeof(char));

        free(blurb);
}
\end{lstlisting}
\end{frame}
\begin{frame}[containsverbatim]
\frametitle{GLIBC eigene Mechanismen: MTrace}
\begin{lstlisting}[language=bash,basicstyle=\ttfamily\fontsize{9}{9}\selectfont]
$ gcc -g -o mem_leak mem_leak.c
$ MALLOC_TRACE=mytrace.log ./mem_leak
$ mtrace ./mem_leak mytrace.log

Memory not freed:
-----------------
Address   Size   Caller
0x1536460 0x1 at /home/jan/work/examples/mem_leak.c:13
0x1536480 0x1 at /home/jan/work/examples/mem_leak.c:13
0x15364a0 0x1 at /home/jan/work/examples/mem_leak.c:13
[...]
\end{lstlisting}
\end{frame}

\subsection{malloc() hooks}
\begin{frame}[containsverbatim]
\frametitle{GLIBC eigene Mechanismen: Hooks für malloc()}
\_\_malloc\_hook:\\
void *function (size\_t size, const void *caller)\\
\_\_realloc\_hook:\\
void *function (void *ptr, size\_t size, const void *caller)\\
\_\_free\_hook:\\
void *function (void *ptr, const void *caller)\\
\_\_memalign\_hook:\\
void *function (size\_t size, size\_t alignment, const void *caller)
\end{frame}
\subsection{libDUMA (aka electric fence)}
\begin{frame}[containsverbatim]
\frametitle{libDUMA / electric fence}
\begin{lstlisting}[language=C,basicstyle=\ttfamily\fontsize{9}{9}\selectfont]
/* mem_leak.c */
#include <duma.h>
#include <malloc.h>
#include <stdio.h>

int main(void)
{
        int i = 0;
        char *blurb = NULL;

        for(i = 0; i < 50; i++)
                blurb = malloc(sizeof(char));

        free(blurb);
}
\end{lstlisting}
\begin{lstlisting}[language=bash,basicstyle=\ttfamily\fontsize{9}{9}\selectfont]
$ gcc -g -o mem_leak mem_leak.c /usr/lib/libduma.a \
   -lpthread
\end{lstlisting}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{libDUMA / electric fence}
\begin{lstlisting}[language=bash,basicstyle=\ttfamily\fontsize{9}{9}\selectfont]
$ ./mem_leak
DUMA 2.5.15 (static library)
Copyright (C) 2006 Michael Eddington
<meddington@gmail.com>
Copyright (C) 2002-2008 Hayati Ayguen
<h_ayguen@web.de>, Procitec GmbH
Copyright (C) 1987-1999 Bruce Perens
<bruce@perens.com>
DUMA: ptr=0x7f7280bdbfff size=1 type='malloc()'
      alloced from mem_leak.c(11) not freed
DUMA: ptr=0x7f7280bddfff size=1 type='malloc()'
      alloced from mem_leak.c(11) not freed
[...]
\end{lstlisting}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{libDUMA / electric fence: Überschriebener Speicher}
\begin{lstlisting}[language=C,basicstyle=\ttfamily\fontsize{8}{8}\selectfont]
/* array_access.c */
#include <stdio.h>
#include <malloc.h>
#include <string.h>

int main(void)
{
        int *my_array = (int*) malloc(10 * sizeof(int));
        int i = 0;
	memset(my_array, 0, 10);

        for(i = 0; i < 11; i++)
                printf("%d ", my_array[i]);

	printf("\n");
        return 0;
}
\end{lstlisting}
\begin{lstlisting}[language=bash,basicstyle=\ttfamily\fontsize{9}{9}\selectfont]
$ gcc -g -o array_access array_access.c
./array_access 0 0 0 0 0 0 0 0 0 0 135121
\end{lstlisting}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{libDUMA / electric fence: Überschriebener Speicher}
\begin{lstlisting}[language=bash,basicstyle=\ttfamily\fontsize{9}{9}\selectfont]
$ gcc -lduma -g -o array_access array_access.c
$ ulimit -c unlimited
$ ./array_access
Segmentation fault (core dumped)
$ gdb array_access core
Loaded symbols for /lib64/ld-linux-x86-64.so.2
Core was generated by `./array_access'.
Program terminated with signal 11, Segmentation fault.
#0  0x00000000004006b7 in main () at array_access.c:10
10                      printf("%d\n", my_array[i]);
(gdb) print i
$1 = 10
\end{lstlisting}
\end{frame}

\begin{frame}[containsverbatim]
\frametitle{libDUMA / electric fence: Überschriebener Speicher}
\begin{lstlisting}[language=bash,basicstyle=\ttfamily\fontsize{9}{9}\selectfont]
$ gcc -g -o array_access array_access.c
$ LD_PRELOAD=/usr/lib/libduma.so ./array_access
Segmentation fault (core dumped)
[...]
\end{lstlisting}
\end{frame}

\subsection{valgrind}
\begin{frame}
\frametitle{Valgrind}
\begin{alertblock}{Vorteile}
\begin{itemize}
\item Sehr hohe Trefferquote
\item Sehr viel Funktionalität
\end{itemize}
\end{alertblock}
\begin{alertblock}{Nachteile}
\begin{itemize}
\item Nur bedingter ARM support (harte Abhängigkeit zu ARMv7)!!!
\end{itemize}
\end{alertblock}
\end{frame}

\begin{frame}[containsverbatim]
\begin{lstlisting}[language=C,basicstyle=\ttfamily\fontsize{9}{9}\selectfont]
/* mem_leak.c */
#include <malloc.h>
#include <stdio.h>

int main(void)
{
        int i = 0;
        char *blurb = NULL;

        for(i = 0; i < 50; i++)
                blurb = malloc(sizeof(char));

        free(blurb);
}
\end{lstlisting}
\begin{lstlisting}[language=bash,basicstyle=\ttfamily\fontsize{9}{9}\selectfont]
$ gcc -g -o mem_leak mem_leak.c
\end{lstlisting}
\end{frame}
\begin{frame}[containsverbatim]
\begin{lstlisting}[basicstyle=\ttfamily\fontsize{9}{9}\selectfont]
$ valgrind --leak-check=full ./mem_leak
=5764= Memcheck, a memory error detector
=5764= Copyright (C) 2002-2009, and GNU GPL'd, by
       Julian Seward et al.
=5764= Using Valgrind-3.6.0.SVN-Debian and LibVEX;
       rerun with -h for copyright info
=5764= Command: ./mem_leak
=5764= 
=5764= HEAP SUMMARY:
=5764=     in use at exit: 49 bytes in 49 blocks
=5764=   total heap usage: 50 allocs, 1 frees,
=5764=                        50 bytes allocated
=5764= 49 bytes in 49 blocks are definitely lost in
=5764=                             loss record 1 of 1
=5764=  at 0x4C274A8: malloc (vg_replace_malloc.c:236)
=5764=  by 0x40058D: main (mem_leak.c:10)
=5764= 
=5764= LEAK SUMMARY:
=5764=    definitely lost: 49 bytes in 49 blocks
[...]
\end{lstlisting}
\end{frame}
\end{document}
