summaryrefslogtreecommitdiff
path: root/application-devel
diff options
context:
space:
mode:
authorJan Altenberg <jan@jan-laptop.(none)>2010-04-23 15:41:59 +0200
committerJan Altenberg <jan@jan-laptop.(none)>2010-04-23 15:41:59 +0200
commitae303294cc741b9498816a0c6d1540074c364ded (patch)
tree8e36efe0bdf2201c32946dd3e00895b0723d2b80 /application-devel
parenta27c72e072813081e79798db5e54deaa5b7ad5d5 (diff)
Started debugging chapter.
Diffstat (limited to 'application-devel')
-rw-r--r--application-devel/app-debugging/handout_app-debugging_de.tex286
-rw-r--r--application-devel/app-debugging/hints_app-debugging_de.tex13
-rw-r--r--application-devel/app-debugging/pres_app-debugging_de.tex66
3 files changed, 66 insertions, 299 deletions
diff --git a/application-devel/app-debugging/handout_app-debugging_de.tex b/application-devel/app-debugging/handout_app-debugging_de.tex
index 89c71c2..b6e7158 100644
--- a/application-devel/app-debugging/handout_app-debugging_de.tex
+++ b/application-devel/app-debugging/handout_app-debugging_de.tex
@@ -6,290 +6,14 @@
\begin{document}
-\section*{Debugging}
+\section*{Titel}
-Beim Debugging geht es darum, Fehler in einem System zu finden.
+\subsection*{Abschnitt1}
-Es gibt zwei grundlegend verschiedene Fehlerarten:
+Text
-\begin{enumerate}
-\item die Anwendung beendet sich unerwartet
- \begin{description}
- \item[auf Grund von Fehlern bei der Speicherveraltung] z.B. durch freigeben
- eines Speicherbereichs, welcher zuvor nicht alloziert wurde:
- \begin{lstlisting}
-mem = malloc(5);
-free(((char*)mem)+6000);
- \end{lstlisting}
- Die Programmausf\"uhrung wird abgebrochen, die glibc liefert alle
- Informationen, welche n\"otig sind, um den Fehler zu decodieren:
- \begin{lstlisting}
-bash-4.0$ ./test
-*** glibc detected *** ./test: free(): invalid pointer: 0x083c9778 ***
-======= Backtrace: =========
-/lib/libc.so.6[0x57c231]
-./test[0x804841e]
-/lib/libc.so.6(__libc_start_main+0xe6)[0x522a66]
-./test[0x8048361]
-======= Memory map: ========
-0048e000-0048f000 r-xp 0048e000 00:00 0 [vdso]
-004e8000-00508000 r-xp 00000000 fd:00 66065 /lib/ld-2.10.1.so
-00508000-00509000 r--p 0001f000 fd:00 66065 /lib/ld-2.10.1.so
-...
- \end{lstlisting}
- Mit folgendem Befehl kann festgestellt werden, von wo aus der Fehler
- getriggered wurde:
-
- \cmd{addr2line -e test 0x804841e}
+\subsection*{Abschnitt2}
- /home/linutronix/test.c:16
-
- \item[Speicherzugriffsfehler] z.B. durch Zugriff auf nicht allozierten
- Speicher. Die Programmausf\"uhrung wird abgebrochen:
- \begin{lstlisting}
-bash-4.0$ ./test
-Speicherzugriffsfehler
- \end{lstlisting}
- Solche Fehler lassen sich am Besten mit einer gdb Backtrace Ausgabe (siehe
- unten) finden.
- \end{description}
-\item die Anwendung verh\"alt sich anders als erwartet.
-
- In einem solchen Fall sollte man sich zu erst Gedanken dar\"uber machen,
- durch was das Fehlverhalten getriggered werden k\"onnte. Sofort mit einem
- Debugger durch den Code zu steppen ist kein guter Ansatz, da so evt. ein
- Fehler gefunden und behoben wird der aber nicht zwangsl\"aufig die Ursache
- f\"ur das Problem war. Dies kann dazu f\"uhren, dass die Fehlersuche eines
- sp\"ater entdeckten Bugs um so komplexer und schwieriger wird.
-
- Hat man sich Gedanken \"uber die Ursachen gemacht, kann man gezielt mit den
- nachfolgend beschriebenen Techniken dem Fehler auf den Grund gehen.
-\end{enumerate}
-
-\subsection*{Einfach aber wirkungsvoll: \cmd{printf}, \cmd{fprintf}}
-
-Da Ausgaben auf die \cmd{stdout} gecached werden, ist es zuverl\"assiger f\"ur
-Debugging \cmd{stderr} zu verwenden und nach jeder Ausgabe noch den cash flush
-zu triggern. Ein Debug konstrukt k\"onnte z.B. folgenderma\ss en aussehen:
-
-\begin{lstlisting}
-fprintf(stderr, "debug test\n");
-fflush(stderr);
-\end{lstlisting}
-
-F\"ur gew\"ohnlich wird \cmd{(f)printf} beim Debuggen f\"ur drei Zwecke
-verwendet:
-
-\begin{enumerate}
-\item Tracing:
-\begin{lstlisting}
-fprintf(stderr, "%s, called\n", __FUNCTION__);
-fflush(stderr);
-\end{lstlisting}
-\item Ausgabe von Variablenwerten:
-\begin{lstlisting}
-fprintf(stderr, "Wert: %d, Wert (hex): %x\n", wert, wert);
-fflush(stderr);
-\end{lstlisting}
-\item Ausgabe von Adressen:
-\begin{lstlisting}
-fprintf(stderr, "Adresse: %p, Wert: %x\n", wert, wert);
-fflush(stderr);
-\end{lstlisting}
-\end{enumerate}
-
-Nat\"urlich k\"onnen die Methoden kombiniert werden.
-
-Soll das Debugging zur Compilezeit zu- und abschaltbar sein, kann z.B. folgendes
-Pr\"aprozessor konstrukt hilfreich sein:
-
-\begin{lstlisting}
-#ifdef DEBUG
-#define debug(...) fprintf(stderr, "%s:%d - ", __FILE__, __LINE__); \
- fprintf(stderr, __VA_ARGS__); fflush(stderr)
-#else
-#define debug(...) ((void)0)
-#endif
-
-int main(int argc, char **argv)
-{
- int val = 3;
- debug("addr: %p - val: %d\n", &val, val);
- return 0;
-}
-\end{lstlisting}
-
-Resultat:
-\begin{lstlisting}
-bash-4.0$ gcc -o test test.c
-bash-4.0$ ./test
-bash-4.0$
-bash-4.0$ gcc -o test -DDEBUG test.c
-bash-4.0$ ./test
-test.c:22 - test: 0xbfef8694 - val: 3
-bash-4.0$
-\end{lstlisting}
-
-\subsubsection*{deutlich flexibler: Logging Frameworks}
-
-Wird f\"ur Debugging oder Logging mehr Flexibilit\"at ben\"otigt, sollte ein
-Logging Framework verwendet werden. Prominente Vertretter f\"ur verschiedene
-Programmiersprachen sind zum Beispiel:
-
-\begin{itemize}
-\item Log for C++ (http://log4cpp.sourceforge.net)
-\item log4c (http://log4c.sourceforge.net)
-\item log4j (http://logging.apache.org/log4j) - f\"ur JAVA
-\end{itemize}
-
-Diese Frameworks bieten die M\"oglichkeit das Loggingverhalten zum Startpunkt
-der Anwendung, oder teilweise sogar, w\"ahrend der Laufzeit zu ver\"andern.
-
-Es wird beim Loggen mindestens zwischen den Kategorien Debug, Error und Info
-unteschieden, welche jeweils an verschiedene Ziele geleitet werden k\"onnen:
-Datei, syslog, \dots
-
-\subsubsection*{Backtraces ausgeben}
-
-Die glibc bietet auch die M\"oglichkeit an einer beliebigen Stelle in der
-Applikation die Ausgabe eines Function Call Traces (Backtrace) aus zu geben.
-
-Dies ist hilfreich, wenn man herausfinden will, \"uber welche Funktionsaufrufe
-die aktuelle Codezeile aufgerufen wurde.
-
-Beispiel:
-\begin{lstlisting}
-#include <stdio.h>
-#include <stdlib.h>
-#define DEFAULT_BT_DEPTH 16
-
-void btrace(int depth) {
- const void *trace[depth];
- char **messages = (char **) NULL;
- unsigned int i = 0;
- int trace_size = backtrace(trace, depth);
- messages = backtrace_symbols(trace, trace_size);
- fprintf(stderr, "***BACKTRACE***\n");
- for(; i < trace_size; i++)
- fprintf(stderr, "%s\n", messages[i]);
- fprintf(stderr, "***************\n");
- fflush(stderr);
-}
-void pong() {
-#ifdef DEBUG
- btrace(DEFAULT_BT_DEPTH);
-#endif
-}
-void ping() {
- pong();
-}
-int main(int argc, char **argv) {
- ping();
- return 0;
-}
-\end{lstlisting}
-
-Anwendung:
-\begin{lstlisting}
-bash-4.0$ gcc -g -o test -DDEBUG test.c
-bash-4.0$ ./test
-***BACKTRACE***
-./test [0x804859b]
-./test [0x8048663]
-./test [0x8048670]
-./test [0x804867d]
-/lib/libc.so.6(__libc_start_main+0xe6) [0x522a66]
-./test [0x8048441]
-***************
-bash-4.0$ addr2line -e test 0x804867d
-/home/linutronix/test.c:27
-bash-4.0$ addr2line -e test 0x8048670
-/home/linutronix/test.c:24
-\end{lstlisting}
-
-\subsection*{Tracing mit strace}
-
-Mit \cmd{strace} k\"onnen Systemaufrufe getraced werden. Es kann ermittelt
-werden welche Systemaufrufe von der Applikation zu welchem Zeitpunkt aufgerufen
-wurden und wieviel Zeit der Kernel ben\"otigt um den Aufruf ab zu arbeiten.
-
-Ein \cmd{strace} ist folgenderma\ss en zu interpretieren:
-
-\begin{lstlisting}
-bash-4.0$ strace -ftttT ./test
-1245687387.873813 execve("./test", ["./test"], [/* 18 vars */]) = 0 <0.000233>
-^ ^ ^ ^ ^
-| | | | |
-| | +- Argumente | +- Dauer
-+- Zeitstempel +- syscall +- Rueckgabewert
-\end{lstlisting}
-
-Die Option
-\begin{itemize}
-\item \cmd{-f} sorgt daf\"ur, dass auch Kindprozesse mit getraced werden,
-\item \cmd{-ttt} blendet den pr\"azisen Zeitstempel ein,
-\item \cmd{-T} gibt die Dauer des Systemaufrufs mit an.
-\end{itemize}
-
-\subsection*{Debugging mit gdb}
-
-gdb ist ein textbasierter Debugger. Eine Applikation kann z.B mit dem Befehl
-\cmd{gdb ./test} in gdb geladen werden und anschliessend mit dem Befehl
-\cmd{run} ausgef\"uhrt werden.
-
-Die 'gdb Reference Card' listet viele n\"utzliche Befehle, z.B. zum Setzen von
-Breakpoints und zum Steppen durch die Applikation.
-
-Es gibt auch grafische Frontends f\"ur gdb, wie z.B. \cmd{ddd}
-(http://www.gnu.org/software/ddd).
-
-\subsubsection*{Core Dumps analysieren}
-
-\cmd{gdb} eignet sich au\ss erdem hervorragend zur Analyse von so genannten
-'core dumps'. Ein 'core dump' entsteht, wenn eine Applikation unerwartet beendet
-wird. Gegebenenfalls mu\ss mit \cmd{ulimit -c unlimited} vor dem
-Applikationsstart das Limit f\"ur maximal zul\"assige core dumps erh\"oht
-werden.
-
-Beispiel:
-\begin{lstlisting}
-bash-4.0$ ulimit -c unlimited
-bash-4.0$ ./test
-Speicherzugriffsfehler (Speicherabzug geschrieben)
-bash-4.0$ gdb ./test core.12371
-GNU gdb 6.8-debian
-Copyright (C) 2008 Free Software Foundation, Inc.
-License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
-This is free software: you are free to change and redistribute it.
-There is NO WARRANTY, to the extent permitted by law. Type "show copying"
-and "show warranty" for details.
-This GDB was configured as "x86_64-linux-gnu"...
-Reading symbols from /lib/libc.so.6...done.
-Loaded symbols for /lib/libc.so.6
-Reading symbols from /lib/ld-linux.so.2...done.
-Loaded symbols for /lib/ld-linux.so.2
-Core was generated by `./test'.
-Program terminated with signal 11, Segmentation fault.
-[New process 12371]
-#0 0x08048661 in pong () at test.c:22
-22 *null_ptr = 3;
-(gdb)
-(gdb) bt
-#0 0x08048661 in pong () at test.c:22
-#1 0x08048671 in ping () at test.c:26
-#2 0x0804867b in main (argc=1, argv=0xbf9921f4) at test.c:29
-(gdb)
-\end{lstlisting}
-
-Der Befehl \cmd{bt} steht f\"ur Backtrace. Die zuletzt aufgerufene Funktion
-steht an Position \#0. Zeigt \#0 nicht auf die eigene Applikationen sondern z.B.
-in die glibc ist es eher warscheinlich, dass der Fehler durch eine nicht
-spezifiezierte Verwendung einer glibc Funktion getriggered wurde. Man sollte in
-diesem Fall zuerst untersuchen, ob die erste Funktion in der eigenen Software,
-einen korrekten glibc call absetzt, bevor die glibc gedebugged wird.
-
-%\subsubsection*{Remote-Debuggging mit gdbserver}
-
-%Text
+Text
\end{document}
diff --git a/application-devel/app-debugging/hints_app-debugging_de.tex b/application-devel/app-debugging/hints_app-debugging_de.tex
index e17f921..11c5c34 100644
--- a/application-devel/app-debugging/hints_app-debugging_de.tex
+++ b/application-devel/app-debugging/hints_app-debugging_de.tex
@@ -1,17 +1,18 @@
-\documentclass{article}
+\documentclass{lxarticle}
\usepackage{german}
\usepackage[utf8]{inputenc}
+\usepackage{lxheaders}
+\usepackage{lxextras}
\begin{document}
-\section*{Block \lq Debugging von Applikationen\rq}
+\section*{Block \lq Was ist Linux?\rq}
\subsection*{Lernziele}
\begin{itemize}
-\item Einfach aber wirkungsvoll: printf
-\item Kennenlernen von strace
-\item Debugging mit gdb
-\item Remote-Debugging mit gdbserver
+\item Lernziel 1
+\item Lernziel 2
+\item Lernziel 3
\end{itemize}
\subsection*{Unterrichts-Ablauf}
diff --git a/application-devel/app-debugging/pres_app-debugging_de.tex b/application-devel/app-debugging/pres_app-debugging_de.tex
index 07db328..1c912b9 100644
--- a/application-devel/app-debugging/pres_app-debugging_de.tex
+++ b/application-devel/app-debugging/pres_app-debugging_de.tex
@@ -1,24 +1,66 @@
-\documentclass{article}
+\documentclass{beamer}
+\usetheme{linutronix}
\usepackage{german}
\usepackage[utf8]{inputenc}
+\usepackage{pgf}
+\usepackage{graphicx}
+\usepackage{lxextras}
+
+\title{Block \lq Was ist Linux?\rq}
+\institute{Linutronix GmbH}
+
+\lstset{keywordstyle=\color{blue},commentstyle=\color{orange}}
\begin{document}
-\section*{Block \lq Was ist Linux?\rq}
+\maketitle
+\begin{frame}
+\frametitle{Übersicht}
+\tableofcontents
+\end{frame}
-\subsection*{Lernziele}
-\begin{itemize}
-\item Lernziel 1
-\item Lernziel 2
-\item Lernziel 3
-\end{itemize}
+\section{Einfache Debugging Werkzeuge}
+\subsection{System calls 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}
-\subsection*{Unterrichts-Ablauf}
+\begin{frame}[containsverbatim]
+\frametitle{Anwendungsbeispiel}
+\begin{lstlisting}[language=bash]
+$ 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) =
+0xb7f03000
+access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
+open("/etc/ld.so.cache", O_RDONLY) = 3
+fstat64(3, {st_mode=S_IFREG|0644, st_size=113431, ...}) = 0
+[...]
+\end{lstlisting}
+\end{frame}
-Hinweise zur Präsentation, Zeitplanung, etc.
+\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}
-\subsection*{Übungen bei vorhandener Hardware}
+\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}
-Hinweise zu Übungen, Zeitlimit dazu.
\end{document}