From dd97dffcfb8e49c611d338fccce898ac65a8f25a Mon Sep 17 00:00:00 2001 From: Sergio Durigan Junior Date: Thu, 16 Oct 2014 18:47:50 -0400 Subject: [PATCH] Adding slides in en_US This commit adds the slides in en_US, and also the examples. --- Makefile | 12 + examples/corefile/1.c | 28 ++ examples/multi-process/Makefile | 7 + examples/multi-process/README | 10 + examples/multi-process/segv.c | 9 + examples/python/caller_is/1.c | 25 ++ examples/python/caller_is/README | 1 + examples/python/caller_is/caller_is.py | 20 ++ examples/python/pretty-print/1.c | 42 +++ examples/python/pretty-print2/1.cpp | 9 + examples/python/pretty-print2/str.py | 29 ++ examples/reverse/1.c | 23 ++ examples/reverse/1.h | 1 + examples/reverse/2.c | 17 + examples/reverse/2.h | 3 + examples/stap-probe/1.c | 41 +++ examples/stap-probe/README | 2 + examples/stap-probe/baz.c | 12 + gdb-best-friend.tex | 413 +++++++++++++++++++++++++ 19 files changed, 704 insertions(+) create mode 100644 Makefile create mode 100644 examples/corefile/1.c create mode 100644 examples/multi-process/Makefile create mode 100644 examples/multi-process/README create mode 100644 examples/multi-process/segv.c create mode 100644 examples/python/caller_is/1.c create mode 100644 examples/python/caller_is/README create mode 100644 examples/python/caller_is/caller_is.py create mode 100644 examples/python/pretty-print/1.c create mode 100644 examples/python/pretty-print2/1.cpp create mode 100644 examples/python/pretty-print2/str.py create mode 100644 examples/reverse/1.c create mode 100644 examples/reverse/1.h create mode 100644 examples/reverse/2.c create mode 100644 examples/reverse/2.h create mode 100644 examples/stap-probe/1.c create mode 100644 examples/stap-probe/README create mode 100644 examples/stap-probe/baz.c create mode 100644 gdb-best-friend.tex diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..b1ab456 --- /dev/null +++ b/Makefile @@ -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} diff --git a/examples/corefile/1.c b/examples/corefile/1.c new file mode 100644 index 0000000..1a7c340 --- /dev/null +++ b/examples/corefile/1.c @@ -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; +} diff --git a/examples/multi-process/Makefile b/examples/multi-process/Makefile new file mode 100644 index 0000000..c8b9097 --- /dev/null +++ b/examples/multi-process/Makefile @@ -0,0 +1,7 @@ +all: run + +run: segv + ./segv + +segv: segv.c + gcc -g -o segv segv.c diff --git a/examples/multi-process/README b/examples/multi-process/README new file mode 100644 index 0000000..4195dd2 --- /dev/null +++ b/examples/multi-process/README @@ -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 diff --git a/examples/multi-process/segv.c b/examples/multi-process/segv.c new file mode 100644 index 0000000..f09c0bc --- /dev/null +++ b/examples/multi-process/segv.c @@ -0,0 +1,9 @@ +int +main (int argc, char *argv[]) +{ + int *x = 0; + + *x = 52; + + return 0; +} diff --git a/examples/python/caller_is/1.c b/examples/python/caller_is/1.c new file mode 100644 index 0000000..65e5f34 --- /dev/null +++ b/examples/python/caller_is/1.c @@ -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; +} diff --git a/examples/python/caller_is/README b/examples/python/caller_is/README new file mode 100644 index 0000000..8c25307 --- /dev/null +++ b/examples/python/caller_is/README @@ -0,0 +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 diff --git a/examples/python/caller_is/caller_is.py b/examples/python/caller_is/caller_is.py new file mode 100644 index 0000000..33bdfce --- /dev/null +++ b/examples/python/caller_is/caller_is.py @@ -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() diff --git a/examples/python/pretty-print/1.c b/examples/python/pretty-print/1.c new file mode 100644 index 0000000..bc2f9f9 --- /dev/null +++ b/examples/python/pretty-print/1.c @@ -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; +} diff --git a/examples/python/pretty-print2/1.cpp b/examples/python/pretty-print2/1.cpp new file mode 100644 index 0000000..dd3f378 --- /dev/null +++ b/examples/python/pretty-print2/1.cpp @@ -0,0 +1,9 @@ +#include + +int +main () +{ + std::string x = "Hello Upstream"; + + return 0; +} diff --git a/examples/python/pretty-print2/str.py b/examples/python/pretty-print2/str.py new file mode 100644 index 0000000..6d80b6b --- /dev/null +++ b/examples/python/pretty-print2/str.py @@ -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) diff --git a/examples/reverse/1.c b/examples/reverse/1.c new file mode 100644 index 0000000..32de183 --- /dev/null +++ b/examples/reverse/1.c @@ -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; +} diff --git a/examples/reverse/1.h b/examples/reverse/1.h new file mode 100644 index 0000000..bd26dfc --- /dev/null +++ b/examples/reverse/1.h @@ -0,0 +1 @@ +void foo (int v); diff --git a/examples/reverse/2.c b/examples/reverse/2.c new file mode 100644 index 0000000..6f22119 --- /dev/null +++ b/examples/reverse/2.c @@ -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; +} diff --git a/examples/reverse/2.h b/examples/reverse/2.h new file mode 100644 index 0000000..90955dd --- /dev/null +++ b/examples/reverse/2.h @@ -0,0 +1,3 @@ +void initialize (void); + +void bar (int *v); diff --git a/examples/stap-probe/1.c b/examples/stap-probe/1.c new file mode 100644 index 0000000..c61a92f --- /dev/null +++ b/examples/stap-probe/1.c @@ -0,0 +1,41 @@ +#include + +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; +} diff --git a/examples/stap-probe/README b/examples/stap-probe/README new file mode 100644 index 0000000..4646f00 --- /dev/null +++ b/examples/stap-probe/README @@ -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. diff --git a/examples/stap-probe/baz.c b/examples/stap-probe/baz.c new file mode 100644 index 0000000..c95af1b --- /dev/null +++ b/examples/stap-probe/baz.c @@ -0,0 +1,12 @@ +struct baz + { + int a; + char b; + union + { + int c; + char d; + } u; + }; + +struct baz blabla; diff --git a/gdb-best-friend.tex b/gdb-best-friend.tex new file mode 100644 index 0000000..285188c --- /dev/null +++ b/gdb-best-friend.tex @@ -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 }.} + \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}