Modifications made with Francesco + remove useless section title slides
This commit is contained in:
parent
f350dfa4d6
commit
93dcc441a3
1 changed files with 62 additions and 196 deletions
258
slides.tex
258
slides.tex
|
@ -43,7 +43,7 @@
|
||||||
\newcommand{\cmark}{\color{OliveGreen}\ding{52}}
|
\newcommand{\cmark}{\color{OliveGreen}\ding{52}}
|
||||||
\newcommand{\xmark}{\color{BrickRed}\ding{56}}
|
\newcommand{\xmark}{\color{BrickRed}\ding{56}}
|
||||||
|
|
||||||
\AtBeginSection{
|
\newcommand{\sectiontitleframe}{
|
||||||
\begin{frame}
|
\begin{frame}
|
||||||
\vfill
|
\vfill
|
||||||
\centering
|
\centering
|
||||||
|
@ -51,8 +51,7 @@
|
||||||
\usebeamerfont{title}\insertsectionhead\par%
|
\usebeamerfont{title}\insertsectionhead\par%
|
||||||
\end{beamercolorbox}
|
\end{beamercolorbox}
|
||||||
\vfill
|
\vfill
|
||||||
\end{frame}
|
\end{frame}}
|
||||||
}
|
|
||||||
|
|
||||||
\lstdefinelanguage{gdb}{
|
\lstdefinelanguage{gdb}{
|
||||||
morekeywords={gdb},
|
morekeywords={gdb},
|
||||||
|
@ -68,8 +67,8 @@
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\title[\sectionline] {Reliable and Fast DWARF-based Stack Unwinding}
|
\title[\sectionline] {Reliable and Fast DWARF-based Stack Unwinding}
|
||||||
\author[\slidecountline]{\textbf{Théophile Bastian},\\
|
\author[\slidecountline]{\textbf{Théophile Bastian}\\
|
||||||
\textbf{Stephen Kell}, \\
|
\textbf{Stephen Kell} \\
|
||||||
\textbf{Francesco Zappa Nardelli}}
|
\textbf{Francesco Zappa Nardelli}}
|
||||||
\date{}
|
\date{}
|
||||||
%\subject{}
|
%\subject{}
|
||||||
|
@ -84,15 +83,11 @@
|
||||||
|
|
||||||
\vspace{-2em}
|
\vspace{-2em}
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\begin{align*}
|
{\large \url{https://huit.re/frdwarf}}\\
|
||||||
\text{Slides: } &\text{\todo{add URL for this PDF}} \\
|
{\todo{font size} Slides, paper, code}
|
||||||
\end{align*}
|
|
||||||
\end{center}
|
|
||||||
\end{frame}
|
|
||||||
|
|
||||||
\begin{frame}{~}
|
\todo{FUNDING: ONR Vertica + Google Research Fellowship (logos)}
|
||||||
\addtocounter{framenumber}{-1}
|
\end{center}
|
||||||
\tableofcontents[hideallsubsections]
|
|
||||||
\end{frame}
|
\end{frame}
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
@ -101,27 +96,18 @@
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\subsection{Introduction}
|
\subsection{Introduction}
|
||||||
|
|
||||||
\begin{frame}[fragile]{We often use stack unwinding!}
|
\begin{frame}[fragile]{}
|
||||||
\begin{columns}[c]
|
\begin{columns}[c]
|
||||||
\begin{column}{0.70\textwidth}
|
\begin{column}{0.70\textwidth}
|
||||||
\begin{lstlisting}[language=gdb, numbers=none, escapechar=|]
|
\begin{lstlisting}[language=gdb, numbers=none, escapechar=|]
|
||||||
Program received signal SIGSEGV.
|
$ ./a.out
|
||||||
0x54625 in fct_b at segfault.c:5
|
Segmentation fault.
|
||||||
5 printf("%l\n", *b);
|
|
||||||
|
|
||||||
|\pause| (gdb) backtrace
|
|\pause|(gdb) backtrace
|
||||||
#0 0x54625 in fct_b at segfault.c:5
|
#0 0x54625 in fct_b
|
||||||
#1 0x54663 in fct_a at segfault.c:10
|
#1 0x54663 in fct_a
|
||||||
#2 0x54674 in main at segfault.c:14
|
#2 0x54674 in main
|
||||||
|
|
||||||
|\pause| (gdb) frame 1
|
|
||||||
#1 0x54663 in fct_a at segfault.c:10
|
|
||||||
10 fct_b((int*) a);
|
|
||||||
|
|
||||||
|\pause| (gdb) print a
|
|
||||||
$1 = 84
|
|
||||||
\end{lstlisting}
|
\end{lstlisting}
|
||||||
\vspace{-1em}
|
|
||||||
\pause{}
|
\pause{}
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\textbf{\Large How does it work?!}
|
\textbf{\Large How does it work?!}
|
||||||
|
@ -142,15 +128,11 @@ $1 = 84
|
||||||
\begin{column}{0.55\textwidth}
|
\begin{column}{0.55\textwidth}
|
||||||
\begin{center}
|
\begin{center}
|
||||||
\large\bf
|
\large\bf
|
||||||
How do we get the grandparent RA\@?
|
How do we get the RA\@?\\Easy, \reg{rbp}!
|
||||||
|
|
||||||
\medskip
|
|
||||||
|
|
||||||
Isn't it as trivial as \texttt{pop()}?
|
|
||||||
|
|
||||||
\vspace{2em}
|
\vspace{2em}
|
||||||
|
|
||||||
\onslide<2>{We only have \reg{rsp} and \reg{rip}.}
|
\onslide<2>{What if we only have \reg{rsp}?}
|
||||||
|
|
||||||
\end{center}
|
\end{center}
|
||||||
\end{column}
|
\end{column}
|
||||||
|
@ -280,7 +262,7 @@ $1 = 84
|
||||||
follows a bad pointer, \alert{I’ll reconsider}.''
|
follows a bad pointer, \alert{I’ll reconsider}.''
|
||||||
}
|
}
|
||||||
\newcommand{\LinusSource}{
|
\newcommand{\LinusSource}{
|
||||||
\hfill ---~Linus Torvalds, Kernel mailing list, 2012
|
\hfill ---~Linus Torvalds, 2012
|
||||||
}
|
}
|
||||||
\begin{frame}{A debugging hell: Linux kernel}
|
\begin{frame}{A debugging hell: Linux kernel}
|
||||||
\LinusMailOne{}
|
\LinusMailOne{}
|
||||||
|
@ -307,7 +289,8 @@ $1 = 84
|
||||||
\end{frame}
|
\end{frame}
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\section{Unwinding data as an abstract state}
|
\section{Unwinding data as an abstract execution of the assembly}
|
||||||
|
\sectiontitleframe{}
|
||||||
|
|
||||||
\newcommand{\tblrowval}[4]{#1 & #2 & \only<2->{#3} & \only<2->{#4} \\}
|
\newcommand{\tblrowval}[4]{#1 & #2 & \only<2->{#3} & \only<2->{#4} \\}
|
||||||
\newcommand{\blknote}[1]
|
\newcommand{\blknote}[1]
|
||||||
|
@ -353,17 +336,16 @@ $1 = 84
|
||||||
\blknote{
|
\blknote{
|
||||||
\centering
|
\centering
|
||||||
\begin{overlayarea}{0.9\textwidth}{4.8ex}
|
\begin{overlayarea}{0.9\textwidth}{4.8ex}
|
||||||
\only<3>{Upon function call, \alert{ra = *(\reg{rsp})} (ABI)}
|
\only<3>{Upon function call, \alert{ra = *(\reg{rsp})}}
|
||||||
\only<4>{\texttt{push} decreases \reg{rsp} by 8: %
|
\only<4>{\texttt{push} decreases \reg{rsp} by 8: %
|
||||||
\alert{ra = *(\reg{rsp} + 8)}}
|
\alert{ra = *(\reg{rsp} + 8)}}
|
||||||
\only<5>{and again: %
|
\only<5>{and again: %
|
||||||
\alert{ra = *(\reg{rsp} + 16)}}
|
\alert{ra = *(\reg{rsp} + 16)}}
|
||||||
\only<6>{This \texttt{mov} leaves \reg{rsp} untouched: %
|
\only<6>{This \texttt{mov} leaves \reg{rsp} untouched: %
|
||||||
\alert{ra = *(\reg{rsp} + 16)}}
|
\alert{ra = *(\reg{rsp} + 16)}}
|
||||||
\only<7>{The unwinding table can actually be seen as\\
|
\only<7>{The unwinding table captures an \alert{abstract execution}
|
||||||
an \alert{abstract interpretation} of the code\ldots}
|
of the code\ldots}
|
||||||
\only<8>{\ldots and thus, for a given run, be
|
\only<8>{\ldots and thus can be \alert{synthesized from the binary}.}
|
||||||
\alert{re-computed from scratch}}
|
|
||||||
\end{overlayarea}
|
\end{overlayarea}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -372,79 +354,38 @@ $1 = 84
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\section{Unwinding data synthesis from binaries}
|
\section{Unwinding data synthesis from binaries}
|
||||||
|
|
||||||
\begin{frame}{Why would synthesis be useful?}
|
%\begin{frame}{Why would synthesis be useful?}
|
||||||
\begin{itemize}
|
% \begin{itemize}
|
||||||
\item As said earlier, \alert{DWARF is complex}
|
% \item As said earlier, \alert{DWARF is complex}
|
||||||
\item Some compilers \alert{do not generate it}: hard to \alert{debug}
|
% \item Some compilers \alert{do not generate it}: hard to \alert{debug}
|
||||||
\& \alert{profile}.
|
% \& \alert{profile}.
|
||||||
\item Think of \alert{JIT-compiled assembly} (eg. JVM)
|
% \item Think of \alert{JIT-compiled assembly} (eg. JVM)
|
||||||
\item \ldots{}or even \alert{hand-written inlined assembly}!
|
% \item \ldots{}or even \alert{hand-written inlined assembly}!
|
||||||
\begin{itemize}
|
% \begin{itemize}
|
||||||
\item Painful enough to write for not bothering with DWARF
|
% \item Painful enough to write for not bothering with DWARF
|
||||||
\item May not even be known by the programmer, breaks gdb
|
% \item May not even be known by the programmer, breaks gdb
|
||||||
\item May be wrong (remember Linus!)
|
% \item May be wrong (remember Linus!)
|
||||||
\end{itemize}
|
% \end{itemize}
|
||||||
\end{itemize}
|
% \end{itemize}
|
||||||
\end{frame}
|
%\end{frame}
|
||||||
|
|
||||||
\begin{frame}{What have we got so far?}
|
|
||||||
We now want to \alert{synthesize unwinding data}. That means
|
|
||||||
\alert{forgetting the blue part of the previous schemes}.
|
|
||||||
|
|
||||||
|
\begin{frame}{How do we actually synthesize?}
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item Upon entering a function, we know (ABI)
|
\item Upon entering a function, we know (ABI)
|
||||||
\[ \cfa = \reg{rsp} - 8
|
\[ \cfa = \reg{rsp} - 8
|
||||||
\qquad \ra = \cfa + 8 \]
|
\qquad \ra = \cfa + 8 \]
|
||||||
\item For each instruction, we know \alert{how it changes \cfa}.
|
\item The semantics of each instruction specifies \alert{how it changes \cfa}.
|
||||||
\item We assume \alert{\ra{} constant wrt. \cfa}.
|
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item[$\leadsto$] only \cfa{} tracking matters (for unwinding)
|
\item Heuristic to decide whether we index with \reg{rbp} or
|
||||||
\end{itemize}
|
\reg{rsp}
|
||||||
\item We had a working strategy for a \alert{linear execution}
|
|
||||||
\item We still have to handle
|
|
||||||
\begin{itemize}
|
|
||||||
\item \alert{\cfa{} expression}
|
|
||||||
\item \alert{control flow graph}
|
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
|
\item By performing a symbolic execution, we can \alert{synthesize the
|
||||||
|
unwinding table} line by line.
|
||||||
|
\item Control flow: forward data-flow analysis
|
||||||
|
\item The fixpoints are immediate, cf article
|
||||||
\end{itemize}
|
\end{itemize}
|
||||||
\end{frame}
|
\end{frame}
|
||||||
|
|
||||||
\begin{frame}{\cfa{} expression}
|
|
||||||
Two possibilities:
|
|
||||||
\begin{itemize}
|
|
||||||
\item Either we track \cfa{} wrt. \reg{rsp}
|
|
||||||
\begin{itemize}
|
|
||||||
\item and update it after each instruction if needed
|
|
||||||
\end{itemize}
|
|
||||||
\item Or \reg{rbp} is used as base pointer: easy
|
|
||||||
\end{itemize}
|
|
||||||
\end{frame}
|
|
||||||
|
|
||||||
\begin{frame}{Control flow graph}
|
|
||||||
\begin{columns}[c]
|
|
||||||
\column{0.4\textwidth}
|
|
||||||
\lstinputlisting[language=C]{src/cfg/cfg.c}
|
|
||||||
|
|
||||||
\column{0.30\textwidth}
|
|
||||||
\begin{figure}
|
|
||||||
\centering
|
|
||||||
\includegraphics[width=\textwidth]{src/cfg/cfg.png}
|
|
||||||
\end{figure}
|
|
||||||
\end{columns}
|
|
||||||
|
|
||||||
\begin{itemize}
|
|
||||||
\item \alert{Upon split} (eg. \texttt{X})\alert{:} nothing special,
|
|
||||||
propagate end state of X to child nodes A and B
|
|
||||||
\item \alert{Upon join} (eg. \texttt{while\_end})\alert{:} check
|
|
||||||
consistency of both input states
|
|
||||||
\begin{itemize}
|
|
||||||
\item If tricky, \texttt{gcc} will have used \reg{rbp}, even
|
|
||||||
with \texttt{-fomit-frame-pointer}.
|
|
||||||
\end{itemize}
|
|
||||||
\end{itemize}
|
|
||||||
|
|
||||||
\end{frame}
|
|
||||||
|
|
||||||
\begin{frame}{}
|
\begin{frame}{}
|
||||||
\vfill
|
\vfill
|
||||||
\centering
|
\centering
|
||||||
|
@ -458,6 +399,8 @@ $1 = 84
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\section{Unwinding data compilation}
|
\section{Unwinding data compilation}
|
||||||
|
|
||||||
|
\sectiontitleframe{}
|
||||||
|
|
||||||
\subsection{Compilation ahead-of-time}
|
\subsection{Compilation ahead-of-time}
|
||||||
|
|
||||||
\begin{frame}{Compilation overview}
|
\begin{frame}{Compilation overview}
|
||||||
|
@ -494,7 +437,6 @@ $1 = 84
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item \alert{libunwind}: \textit{de facto} standard library for
|
\item \alert{libunwind}: \textit{de facto} standard library for
|
||||||
unwinding
|
unwinding
|
||||||
\item Relies on DWARF
|
|
||||||
|
|
||||||
\bigskip{}
|
\bigskip{}
|
||||||
|
|
||||||
|
@ -509,98 +451,22 @@ $1 = 84
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\subsection{Results}
|
\subsection{Results}
|
||||||
|
|
||||||
\begin{frame}{Time performance}
|
\begin{frame}{Performances}
|
||||||
\begin{columns}
|
\begin{itemize}
|
||||||
\begin{column}{1.1\textwidth}
|
\item \alert{Speedup}: x15 (\prog{gzip}) to x25 (\prog{hackbench}) vs.
|
||||||
\begin{table}[h]
|
libunwind
|
||||||
\centering
|
|
||||||
\begin{tabular}{l l r r r r r}
|
|
||||||
\toprule
|
|
||||||
& \thead{Unwinding method} & \thead{Frames \\ unwound}
|
|
||||||
& \thead{Tot. time \\ ($\mu s$)}
|
|
||||||
& \thead{Avg. \\ time / frame \\ ($ns$)}
|
|
||||||
& \thead{Time ratio} \\
|
|
||||||
\midrule
|
|
||||||
\midrule
|
|
||||||
|
|
||||||
\multirow{2}{*}{\rotatebox{90}{\textbf{\prog{Gzip}}~~}}
|
\begin{itemize}
|
||||||
&\alert{\ehelfs{}}
|
\item libunwind: state of the art, aggressive caching.
|
||||||
& 331523 % Frames unwound
|
\end{itemize}
|
||||||
& 25930 % Total time
|
|
||||||
& 78 % Avg time
|
|
||||||
& 1
|
|
||||||
\\
|
|
||||||
& \prog{libunwind}, \alert{cached}
|
|
||||||
& 331523 % Frames unwound
|
|
||||||
& 403292 % Total time
|
|
||||||
& 1217 % Avg time
|
|
||||||
& \alert{15.6}
|
|
||||||
\\
|
|
||||||
&\prog{libunwind}, \alert{uncached}
|
|
||||||
& 331523 % Frames unwound
|
|
||||||
& 2197296 % Total time
|
|
||||||
& 6635 % Avg time
|
|
||||||
& \alert{84.7}
|
|
||||||
\\
|
|
||||||
\midrule
|
|
||||||
\multirow{2}{*}{\rotatebox{90}{\textbf{\prog{hackbench}}}}
|
|
||||||
& \alert{\ehelfs{}}
|
|
||||||
& 152297 % Frames unwound
|
|
||||||
& 12941 % Total time
|
|
||||||
& 84 % Avg time
|
|
||||||
& 1
|
|
||||||
\\
|
|
||||||
& \prog{libunwind}, \alert{cached}
|
|
||||||
& 152297 % Frames unwound
|
|
||||||
& 316907 % Total time
|
|
||||||
& 2076 % Avg time
|
|
||||||
& \alert{24.6}
|
|
||||||
\\
|
|
||||||
& \prog{libunwind}, \alert{uncached}
|
|
||||||
& 152297 % Frames unwound
|
|
||||||
& 982697 % Total time
|
|
||||||
& 6439 % Avg time
|
|
||||||
& \alert{76.3}\vspace{0.8em}
|
|
||||||
\\
|
|
||||||
\bottomrule
|
|
||||||
\end{tabular}
|
|
||||||
\end{table}
|
|
||||||
\end{column}
|
|
||||||
\end{columns}
|
|
||||||
\end{frame}
|
|
||||||
|
|
||||||
\begin{frame}{Space overhead}
|
\item \alert{Space overhead}: x2.6 to x3 vs. DWARF
|
||||||
\begin{table}[h]
|
|
||||||
\centering
|
\vspace{2em}
|
||||||
\begin{tabular}{l r r r r}
|
|
||||||
\toprule
|
\item[$\leadsto$] Alternative time/space trade-off, favorable eg. for
|
||||||
\thead{Shared object}
|
profiling.
|
||||||
& \thead{Original \\ \lstinline{.eh\_frame}}
|
\end{itemize}
|
||||||
& \thead{Generated \\ \lstinline{eh_elf} \lstinline{.text}}
|
|
||||||
& \thead{\% of original \\ program size}
|
|
||||||
& \thead{Growth \\ factor} \\
|
|
||||||
\midrule
|
|
||||||
find & 21.3 KiB & 68.3 KiB & 46.63 & 3.21 \\
|
|
||||||
\hfill + libs & 196.6 KiB & 577.2 KiB & 19.75 & 2.94 \\
|
|
||||||
\hline
|
|
||||||
python3.7
|
|
||||||
& 160.0 B & 1.4 KiB & 355.98 & 8.33 \\
|
|
||||||
\hfill + libs
|
|
||||||
& 449.0 KiB & 1.1 MiB & 23.77 & 2.61 \\
|
|
||||||
\hline
|
|
||||||
gzip & 5.1 KiB & 10.9 KiB & 16.48 & 2.13 \\
|
|
||||||
\hfill + libs & 143.5 KiB & 413.1 KiB & 24.96 & 2.88 \\
|
|
||||||
\hline
|
|
||||||
hackbench
|
|
||||||
& 568.0 B & 3.2 KiB & 107.99 & 5.74 \\
|
|
||||||
\hfill + libs
|
|
||||||
& 150.4 KiB & 439.4 KiB & 26.60 & 2.92 \\
|
|
||||||
\hline
|
|
||||||
sqlite & 121.7 KiB & 382.8 KiB & 34.68 & 3.14 \\
|
|
||||||
\hfill + libs & 376.2 KiB & 1.1 MiB & 25.32 & 3.00 \\
|
|
||||||
\bottomrule
|
|
||||||
\end{tabular}
|
|
||||||
\end{table}
|
|
||||||
\end{frame}
|
\end{frame}
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
Loading…
Reference in a new issue