From ae303294cc741b9498816a0c6d1540074c364ded Mon Sep 17 00:00:00 2001
From: Jan Altenberg <jan@jan-laptop.(none)>
Date: Fri, 23 Apr 2010 15:41:59 +0200
Subject: Started debugging chapter.

---
 .../app-debugging/handout_app-debugging_de.tex     | 286 +--------------------
 1 file changed, 5 insertions(+), 281 deletions(-)

(limited to 'application-devel/app-debugging/handout_app-debugging_de.tex')

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}
-- 
cgit v1.2.3

