diff options
| author | Jan Altenberg <jan@bender.lan> | 2010-04-28 17:03:02 +0200 |
|---|---|---|
| committer | Jan Altenberg <jan@bender.lan> | 2010-04-28 17:03:02 +0200 |
| commit | 600b08dbd313480ec9bb0408288ae2d7dc314675 (patch) | |
| tree | 494cf44482241c98c28df5af5ca936a1e46e1a44 /application-devel | |
| parent | 5a8f9ab77eb365fb9e3d98dde9bfa30f5e061896 (diff) | |
App-Debugging: First usable version
- STRACE
- GDB basics
- GDB remote debugging
- GDB core dump analysis
- Memory debugging: MTrace, libDUMA / efence, valgrind
Diffstat (limited to 'application-devel')
| -rw-r--r-- | application-devel/app-debugging/images/remote_debug.png | bin | 0 -> 21795 bytes | |||
| -rw-r--r-- | application-devel/app-debugging/pres_app-debugging_de.tex | 434 |
2 files changed, 423 insertions, 11 deletions
diff --git a/application-devel/app-debugging/images/remote_debug.png b/application-devel/app-debugging/images/remote_debug.png Binary files differnew file mode 100644 index 0000000..f7a3ba9 --- /dev/null +++ b/application-devel/app-debugging/images/remote_debug.png diff --git a/application-devel/app-debugging/pres_app-debugging_de.tex b/application-devel/app-debugging/pres_app-debugging_de.tex index 1c912b9..d9482d9 100644 --- a/application-devel/app-debugging/pres_app-debugging_de.tex +++ b/application-devel/app-debugging/pres_app-debugging_de.tex @@ -6,7 +6,9 @@ \usepackage{graphicx} \usepackage{lxextras} -\title{Block \lq Was ist Linux?\rq} +\lstset{keywordstyle=\color{blue},commentstyle=\color{orange}} + +\title{Block \lq Debugging\rq} \institute{Linutronix GmbH} \lstset{keywordstyle=\color{blue},commentstyle=\color{orange}} @@ -20,7 +22,7 @@ \end{frame} \section{Einfache Debugging Werkzeuge} -\subsection{System calls tracen mit STRACE} +\subsection{Systemcalls tracen mit STRACE} \begin{frame} \frametitle{STRACE} \begin{alertblock}{Was ist STRACE?} @@ -31,16 +33,16 @@ tracen lassen. \begin{frame}[containsverbatim] \frametitle{Anwendungsbeispiel} -\begin{lstlisting}[language=bash] +\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 (No such file or directory) -mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = +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 (No such file or directory) +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, ...}) = 0 +fstat64(3, {st_mode=S_IFREG|0644, st_size=113431, ...} [...] \end{lstlisting} \end{frame} @@ -55,12 +57,422 @@ fstat64(3, {st_mode=S_IFREG|0644, st_size=113431, ...}) = 0 \end{itemize} \end{frame} -\subsection{Memory debugging} -\subsubsection{MTrace} -\subsubsection{libDUMA (aka electric fence)} \section{Der GNU Debugger: GDB} -\subsection{Post mortem Analyse mit 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 & core dumpt 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 & Aktuelles Namenspattern für core files anzeigen \\ +\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{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: Überschriebender 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} + +\frametitle{libDUMA / electric fence: Überschriebener Speicher} +\begin{frame}[containsverbatim] +\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} + +\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}[language=bash,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} |
