A Makefile => Makefile +12 -0
@@ 0,0 1,12 @@
+CC = pdflatex
+TARGET = gdb-best-friend
+EXTENSION = tex
+
+all:
+ set -e ; \
+ for i in 1 2 ; do \
+ $(CC) $(TARGET).$(EXTENSION) ; \
+ done ;
+
+clean:
+ rm -f $(TARGET).{aux,log,nav,out,pdf,snm,toc,vrb}
A examples/corefile/1.c => examples/corefile/1.c +28 -0
@@ 0,0 1,28 @@
+static void foo_segv (void);
+
+static void
+bar (void)
+{
+ foo_segv ();
+}
+
+static void
+foo_segv (void)
+{
+ int *x = 0;
+
+ *x = 5;
+}
+
+static void
+baz (void)
+{
+ bar ();
+}
+
+int
+main (int argc, char *argv[])
+{
+ baz ();
+ return 0;
+}
A examples/multi-process/Makefile => examples/multi-process/Makefile +7 -0
@@ 0,0 1,7 @@
+all: run
+
+run: segv
+ ./segv
+
+segv: segv.c
+ gcc -g -o segv segv.c
A examples/multi-process/README => examples/multi-process/README +10 -0
@@ 0,0 1,10 @@
+Execute:
+
+~/work/src/git/build/gdb/gdb -q make
+
+(gdb) set detach-on-fork off
+(gdb) set target-async on
+(gdb) set non-stop on
+(gdb) set pagination off
+
+inferior 7
A examples/multi-process/segv.c => examples/multi-process/segv.c +9 -0
@@ 0,0 1,9 @@
+int
+main (int argc, char *argv[])
+{
+ int *x = 0;
+
+ *x = 52;
+
+ return 0;
+}
A examples/python/caller_is/1.c => examples/python/caller_is/1.c +25 -0
@@ 0,0 1,25 @@
+static void
+foo (void)
+{
+}
+
+static void
+bar (void)
+{
+ foo ();
+}
+
+static void
+baz (void)
+{
+ foo ();
+}
+
+int
+main (int argc, char *argv[])
+{
+ baz ();
+ bar ();
+
+ return 0;
+}
A examples/python/caller_is/README => examples/python/caller_is/README +1 -0
@@ 0,0 1,1 @@
+~/work/src/git/build/gdb/gdb -q ./a.out --data-directory ~/work/src/git/build/gdb/data-directory -ex 'source caller_is.py' -ex 'b foo if $caller_is ("bar")' -ex run
A examples/python/caller_is/caller_is.py => examples/python/caller_is/caller_is.py +20 -0
@@ 0,0 1,20 @@
+import gdb
+class CallerIs (gdb.Function):
+ """Return True if the calling function's name is equal to a string.
+This function takes one or two arguments.
+The first argument is the name of a function; if the calling function's
+name is equal to this argument, this function returns True.
+The optional second argument tells this function how many stack frames
+to traverse to find the calling function. The default is 1."""
+
+ def __init__ (self):
+ super (CallerIs, self).__init__ ("caller_is")
+
+ def invoke (self, name, nframes = 1):
+ frame = gdb.selected_frame ()
+ while nframes > 0:
+ frame = frame.older ()
+ nframes = nframes - 1
+ return frame.name () == name.string ()
+
+CallerIs()
A examples/python/pretty-print/1.c => examples/python/pretty-print/1.c +42 -0
@@ 0,0 1,42 @@
+struct foo
+ {
+ int a;
+ int b;
+ char c;
+ float d;
+ double e;
+ struct
+ {
+ int s1;
+ char s2;
+ int s3;
+ union
+ {
+ int u1;
+ char u2;
+ double u3;
+ } my_union;
+
+ struct
+ {
+ int crazy_1;
+ union
+ {
+ struct
+ {
+ int big_field;
+ char my_char;
+ };
+ int blabla;
+ } union_2;
+ } my_inner;
+ } my_inner2;
+ };
+
+int
+main (int argc, char *argv[])
+{
+ struct foo a;
+
+ return 0;
+}
A examples/python/pretty-print2/1.cpp => examples/python/pretty-print2/1.cpp +9 -0
@@ 0,0 1,9 @@
+#include <string>
+
+int
+main ()
+{
+ std::string x = "Hello Upstream";
+
+ return 0;
+}
A examples/python/pretty-print2/str.py => examples/python/pretty-print2/str.py +29 -0
@@ 0,0 1,29 @@
+import gdb.printing
+import re
+
+class StdStringPrinter:
+
+ def __init__ (self, val):
+ self.val = val
+
+ def to_string (self):
+ return self.val['_M_dataplus']['_M_p']
+
+ def display_hint (self):
+ return 'string'
+
+def str_lookup_function(val):
+ bbb = {}
+ try:
+ bbb = val.type.fields ()
+ except:
+ pass
+ found = 0
+ for x in bbb:
+ if x.name == '_M_dataplus':
+ found = 1
+ if found == 1:
+ return StdStringPrinter(val)
+ return None
+
+gdb.printing.register_pretty_printer (gdb, str_lookup_function)
A examples/reverse/1.c => examples/reverse/1.c +23 -0
@@ 0,0 1,23 @@
+#include "2.h"
+
+void
+foo (int v)
+{
+ int a = 0;
+
+ a = 10 + 20;
+ a += v;
+
+ bar (&a);
+ bar (0);
+
+ a = 0;
+}
+
+int
+main (int argc, char *argv[])
+{
+ initialize ();
+
+ return 0;
+}
A examples/reverse/1.h => examples/reverse/1.h +1 -0
@@ 0,0 1,1 @@
+void foo (int v);
A examples/reverse/2.c => examples/reverse/2.c +17 -0
@@ 0,0 1,17 @@
+#include "1.h"
+
+void
+initialize (void)
+{
+ int n = 0;
+
+ n = 12314314 % 453;
+ foo (n);
+}
+
+void
+bar (int *v)
+{
+ if (v != 0)
+ *v += 12314314 % 453;
+}
A examples/reverse/2.h => examples/reverse/2.h +3 -0
@@ 0,0 1,3 @@
+void initialize (void);
+
+void bar (int *v);
A examples/stap-probe/1.c => examples/stap-probe/1.c +41 -0
@@ 0,0 1,41 @@
+#include <sys/sdt.h>
+
+struct baz
+ {
+ int a;
+ char b;
+ union
+ {
+ int c;
+ char d;
+ } u;
+ };
+
+static void
+foo (int a, const char *b)
+{
+ STAP_PROBE2 (test, probefoo, a, b);
+}
+
+static void
+bar (const struct baz *a)
+{
+ STAP_PROBE1 (test, probebar, a);
+}
+
+int
+main (int argc, char *argv[])
+{
+ int i1 = 1;
+ const char *s = "String test";
+ struct baz b;
+
+ b.a = 49;
+ b.b = 'y';
+ b.u.d = 'a';
+
+ foo (i1, s);
+ bar (&b);
+
+ return 0;
+}
A examples/stap-probe/README => examples/stap-probe/README +2 -0
@@ 0,0 1,2 @@
+Compiling with -Ox (x > 0) changes the layout of the symbols in the memory.
+If you want to access a structure field, refer to it explicitly in the probe argument.
A examples/stap-probe/baz.c => examples/stap-probe/baz.c +12 -0
@@ 0,0 1,12 @@
+struct baz
+ {
+ int a;
+ char b;
+ union
+ {
+ int c;
+ char d;
+ } u;
+ };
+
+struct baz blabla;
A gdb-best-friend.tex => gdb-best-friend.tex +413 -0
@@ 0,0 1,413 @@
+\documentclass[slidestop,compress,blue]{beamer}
+%\usetheme{default}
+%\usetheme{Malmoe}
+%\usetheme{Boadilla}
+%\usetheme{umbc2}
+%\usetheme{Antibes}
+%\usetheme{Berlin}
+%\usetheme{Madrid}
+
+% Pacotes úteis
+\usepackage[utf8]{inputenc}
+% Fonte bonita!
+\usepackage{ae,aecompl}
+\usepackage[english]{babel}
+\usepackage[T1]{fontenc}
+\usepackage{listings}
+
+\title{GDB, Your New Best Friend}
+\author{Sergio Durigan Junior \\
+ \texttt{sergiodj@\{redhat.com,sergiodj.net\}}}
+\date{\today}
+
+\usetheme[secheader]{Madrid}
+\setbeamertemplate{navigation symbols}{}
+\defbeamertemplate*{footline}{infolines theme without institution}
+{
+ \leavevmode%
+ \hbox{%
+ \begin{beamercolorbox}[wd=.333333\paperwidth,ht=2.25ex,dp=1ex,center]{author in head/foot}%
+ \usebeamerfont{author in head/foot}\insertshortauthor
+ \end{beamercolorbox}%
+ \begin{beamercolorbox}[wd=.333333\paperwidth,ht=2.25ex,dp=1ex,center]{title in head/foot}%
+ \usebeamerfont{title in head/foot}\insertshorttitle
+ \end{beamercolorbox}%
+ \begin{beamercolorbox}[wd=.333333\paperwidth,ht=2.25ex,dp=1ex,right]{date in head/foot}%
+ \usebeamerfont{date in head/foot}\insertshortdate{}\hspace*{2em}
+ \insertframenumber{} / \inserttotalframenumber\hspace*{2ex}
+ \end{beamercolorbox}}%
+ \vskip0pt%
+}
+
+\newcommand{\aspas}[1]{``#1''}
+\newcommand{\gnu}{\texttt{GNU}}
+\newcommand{\gdb}{\texttt{GDB}}
+\newcommand{\gcc}{\texttt{GCC}}
+\newcommand{\stap}{\texttt{SystemTap}}
+\newcommand{\python}{\texttt{Python}}
+\newcommand{\glibc}{\texttt{GLIBC}}
+\newcommand{\kernel}{\textit{kernel}}
+\newcommand{\probe}{\textit{probe}}
+\newtheorem{sourcecode}{Source Code}
+
+\begin{document}
+
+\lstset{escapeinside={(*}{*)}}
+
+\begin{frame}
+ \titlepage
+\end{frame}
+
+\begin{frame}
+ \frametitle{License}
+ \begin{itemize}
+ \item{License: \textbf{Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)}}
+ \item{\url{http://creativecommons.org/licenses/by-sa/3.0/}}
+ \end{itemize}
+\end{frame}
+
+\section{Tópicos}
+\begin{frame}
+ \frametitle{Agenda}
+
+\begin{itemize}
+ \item{Introduction}
+
+% corefile
+ \item{The core of the file}
+
+% Falar de multiprocess
+ \item{Multiprocess}
+
+% Falar de probes, stap
+ \item{\stap{} \texttt{SDT} probes}
+
+% Falar de catchpoints? catch syscall
+% \item{Análise de uma \probe{}}
+
+% Falar de depuração reversa
+ \item{gniggubeD esreveR}
+
+% Falar de Python
+ \item{\python{}}
+
+ \item{Conclusion}
+\end{itemize}
+\end{frame}
+
+\section{Introduction}
+\begin{frame}[fragile]
+ \frametitle{Introduction}
+ \begin{itemize}
+ \item{\gdb{}: \gnu{} project's Debugger \pause{} (it is \textbf{not} a \textit{database}...). Supports several programming languages.}
+ \begin{itemize}
+ \item{\verb|#> gcc -g program.c -o program|}
+ \item{\verb|#> gdb ./program|}
+ \end{itemize}
+ \pause
+ \item{Before anything else! \verb|C-x a|}
+ \end{itemize}
+\end{frame}
+
+\section{The core of the file}
+\begin{frame}[fragile]
+ \frametitle{The core of the file}
+ \begin{itemize}
+ \item{\texttt{corefile}s are ``frozen images'' of a certain point of execution inside a program.}
+ \pause
+ \item{To generate one on \gdb{}, at any time:}
+ \begin{itemize}
+ \item{\verb|(gdb) generate-core-file|}
+ \end{itemize}
+ \pause
+ \item{If you are seeing a segmentation fault, enable the \texttt{corefile} generation in your \texttt{shell}:}
+ \begin{itemize}
+ \item{\verb|#> ulimit -c unlimited|}
+ \end{itemize}
+ \pause
+ \item{And then open the \texttt{corefile} on \gdb{}:}
+ \begin{itemize}
+ \item{\verb|#> gdb program core.12345|}
+ \end{itemize}
+ \pause
+ \item{Inside \gdb{}, almost everything works. You can print variables, request a \texttt{backtrace}, change the current \texttt{frame}. You just cannot ``resurrect'' the program (i.e., execute it from that point) \verb|:-)|.}
+ \end{itemize}
+\end{frame}
+
+\section{Multiprocess}
+\begin{frame}[fragile]
+ \frametitle{Multiprocess}
+ \begin{itemize}
+ \item{Given:}
+ \begin{block}{Makefile}
+ \tiny
+ \begin{lstlisting}[language=sh,showstringspaces=false]
+all: run
+
+run: segv
+ ./segv
+
+segv: segv.c
+ gcc -g -o segv segv.c
+ \end{lstlisting}
+ \end{block}
+ \begin{block}{segv.c}
+ \tiny
+ \begin{lstlisting}[language=c,showstringspaces=false]
+int
+main (int argc, char *argv[])
+{
+ int *x = 0;
+
+ *x = 52;
+
+ return 0;
+}
+ \end{lstlisting}
+ \end{block}
+ \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]
+ \frametitle{Multiprocess$^2$}
+ \begin{itemize}
+ \item{How do you debug the program from the example, which has a segmentation fault?}
+ \pause
+ \item{Multiprocess!}
+ \pause
+ \item{On \gdb{}:}
+ \begin{itemize}
+ \item{\verb|(gdb) set detach-on-fork off|}
+ \item{\verb|(gdb) set target-async on|}
+ \item{\verb|(gdb) set non-stop on|}
+ \item{\verb|(gdb) run|}
+ \item{(...)}
+ \item{\verb|(gdb) info inferiors|}
+ \end{itemize}
+ \item{(Yes, it is boring to type. Yes, we will improve it.)}
+ \pause
+ \item{Time for a hands-on!}
+ \end{itemize}
+\end{frame}
+
+\section{SystemTap SDT probes}
+\begin{frame}[fragile]
+ \frametitle{\stap{} \texttt{SDT} probes}
+ \begin{itemize}
+ \item{Pre-req for \gdb{}: \probe{} v3, \verb|systemtap-sdt-devel >= 1.4|.}
+ \begin{block}{Example code -- \texttt{exemplo-stap.c}}
+ \tiny
+ \begin{lstlisting}[language=c,showstringspaces=false]
+(*\textcolor{red}{\#\textbf{include}} \textcolor{red}{\textless{}sys/sdt.h\textgreater{}}*)
+
+void foo (int a)
+{
+ (*\textcolor{red}{STAP\_PROBE1 (}\textcolor{red}{example-stap, my\_probe, a}\textcolor{red}{);}*)
+}
+
+int main (int argc, char *argv[])
+{
+ foo (10);
+ return 0;
+}
+ \end{lstlisting}
+ \end{block}
+ \pause
+ \begin{block}{Compiling and verifying the \probe{}}
+ \tiny
+ \begin{lstlisting}[language=sh,showstringspaces=false]
+$> gcc exemplo-stap.c -o exemplo-stap
+$> stap -L '(*\textcolor{red}{process("./example-stap").mark("*")}*)'
+process("./example-stap").mark("my_probe") $arg1:long
+ \end{lstlisting}
+ \end{block}
+ \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]
+ \frametitle{\stap{} \texttt{SDT} probes$^2$}
+ \begin{itemize}
+ \item{Available since \gdb{} 7.5, release in August, 2012.}
+ \pause
+ \item{Integrated with the \textit{breakpoint} system. Support for printing a \probe{}'s argument value.}
+ \pause
+ \item{Supports \textit{tracepoints}.}
+ \pause
+ \item{Not necessary to include debug information in your binary (\texttt{-g} flag); arguments are encoded directly in the asm.}
+ \pause
+ \item{Also possible to use optmization flags (\texttt{-O}).}
+ \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]
+ \frametitle{\stap{} \texttt{SDT} probes$^3$}
+ \begin{itemize}
+ \item{Command \texttt{info probes}, list information about available \textit{probes}.}
+ \pause
+ \item{Command \texttt{break -probe-stap <probe\_name>}.}
+ \pause
+ \begin{itemize}
+ \item{Also possible to use \texttt{-probe} or \texttt{-p}.}
+ \end{itemize}
+ \pause
+ \item{Printing arguments for each \probe{}: internal \gdb{} variables.}
+ \begin{itemize}
+ \item{\texttt{\$\_probe\_argc}: number of arguments of the \probe{} (max: 12).}
+ \item{\texttt{\$\_probe\_arg$\{$0..11$\}$}: print argument \{0..11\}.}
+ \end{itemize}
+ \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]
+ \frametitle{\stap{} \texttt{SDT} probes$^4$}
+ \begin{itemize}
+ \item{After compiling your program (as shown previously):}
+ \begin{block}{Debugging \stap{} \texttt{SDT} probes}
+ \tiny
+ \begin{lstlisting}[language=sh,showstringspaces=false]
+\$> gdb /tmp/example-stap
+...
+(gdb) info probes
+Provider Name Where Semaphore Object
+example-stap my_probe 0x000000000040047b /tmp/example-stap
+(gdb) break -probe-stap my_probe
+Breakpoint 1 at 0x40047b
+(gdb) run
+Starting program: /tmp/example-stap
+
+Breakpoint 1, 0x000000000040047b in foo ()
+(gdb) print $_probe_argc
+$1 = 1
+(gdb) print $_probe_arg0
+$2 = 10
+ \end{lstlisting}
+ \end{block}
+ \end{itemize}
+\end{frame}
+
+\section{gniggubeD esreveR}
+\begin{frame}[fragile]
+ \frametitle{gniggubeD esreveR}
+ \begin{itemize}
+ \item{Available since \gdb{} 7.0, released on September, 2009!}
+ \pause
+ \item{Implementation is kind of messy, but works in most cases...}
+ \pause
+ \item{Just works on x86/x86\_64 (patch for PowerPC is being made).}
+ \pause
+ \item{The hacker who did almost everything passed away. \verb|:-(|}
+ \begin{itemize}
+ \item{Old story: ``... if I die, who is going to maintain this code?''}
+ \end{itemize}
+ \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]
+ \frametitle{gniggubeD esreveR$^2$}
+ \begin{itemize}
+ \item{\verb|(gdb) start|}
+ \item{\verb|(gdb) target record-full|}
+ \item{Or, with a recent \gdb{}: \verb|(gdb) record|}
+ \item{(...)}
+ \item{Use the commands with the prefix \texttt{reverse}. \verb|reverse-next, reverse-step, reverse-nexti, reverse-stepi, set exec-direction reverse|...}
+ \end{itemize}
+\end{frame}
+
+
+\section{Python}
+\begin{frame}[fragile]
+ \frametitle{\python{}}
+ \begin{itemize}
+ \item{Available since \gdb{} 7.0, too.}
+ \pause
+ \item{Motivation: make it easy to extend \gdb{} without having to mess with its internals.}
+ \pause
+ \item{Very well maintained, several extensions implemented.}
+ \pause
+ \item{Several projects already make use of it. Yours can be the next! \verb|:-)|}
+ \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]
+ \frametitle{\python{}$^2$}
+ \begin{itemize}
+ \item{Problem: \gdb{} knows about the \texttt{call stack}. \gdb{} also has conditional \texttt{breakpoints}.}
+ \pause
+ \item{\emph{However, you cannot use information from the \texttt{stack} in the condition of a \texttt{breakpoint}.}}
+ \pause
+ \item{Solution? Python!}
+ \end{itemize}
+\end{frame}
+
+\begin{frame}[fragile]
+ \frametitle{\python{}$^3$}
+% \begin{itemize}
+ \begin{block}{caller\_is.py}
+ \tiny
+ \begin{lstlisting}[language=python,showstringspaces=false]
+import gdb
+class CallerIs (gdb.Function):
+ """Return True if the calling function's name is equal to a string.
+This function takes one or two arguments.
+The first argument is the name of a function; if the calling function's
+name is equal to this argument, this function returns True.
+The optional second argument tells this function how many stack frames
+to traverse to find the calling function. The default is 1."""
+
+ def __init__ (self):
+ super (CallerIs, self).__init__ ("caller_is")
+
+ def invoke (self, name, nframes = 1):
+ frame = gdb.selected_frame ()
+ while nframes > 0:
+ frame = frame.older ()
+ nframes = nframes - 1
+ return frame.name () == name.string ()
+
+CallerIs()
+ \end{lstlisting}
+ \end{block}
+\end{frame}
+
+\begin{frame}[fragile]
+ \frametitle{\python{}$^4$}
+ \begin{itemize}
+ \item{\verb|(gdb) source caller_is.py|}
+ \item{\verb|(gdb) break foo if $caller_is ("bar")|}
+ \end{itemize}
+\end{frame}
+
+\section{Conclusion}
+\begin{frame}[fragile]
+ \frametitle{Conclusion}
+ \begin{itemize}
+ \item{The debugger you knew has changed for the better.}
+ \pause
+ \item{Things that are coming:}
+ \begin{itemize}
+ \item{Improvements in the multiprocess feature.}
+ \item{Scalability}
+ \item{Improvements for \texttt{C++}.}
+ \end{itemize}
+ \end{itemize}
+\end{frame}
+
+\section{Thank you's}
+\begin{frame}[fragile]
+ \frametitle{Thank you's}
+ \begin{itemize}
+ \item{Red Hat}
+ \item{FSOSS}
+ \item{You guys and girls \verb|:-)|}
+ \end{itemize}
+\end{frame}
+
+\section{Questions}
+\begin{frame}
+ \frametitle{Questions?}
+ \begin{center}
+ Shoot! Or send e-mail!
+ \end{center}
+\end{frame}
+
+\end{document}