Add unwinding usage
This commit is contained in:
parent
be47fefd98
commit
36de838a89
3 changed files with 70 additions and 4 deletions
|
@ -87,6 +87,49 @@ necessary to have additional data to perform stack unwinding. This data is
|
|||
often stored among the debugging informations of a program, and one common
|
||||
format of debugging data is DWARF\@.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{Unwinding usage and frequency}
|
||||
|
||||
Stack unwinding is a more common operation that one might think at first. The
|
||||
most commonly thought use-case is simply to get a stack trace of a program, and
|
||||
provide a debugger with the information it needs: for instance, when inspecting
|
||||
a stack trace in \prog{gdb}, it is quite common to jump to a previous frame:
|
||||
|
||||
\lstinputlisting{src/segfault/gdb_session}
|
||||
|
||||
To be able to do this, \texttt{gdb} must be able to restore \lstc{fct_a}'s
|
||||
context, by unwinding \lstc{fct_b}'s frame.
|
||||
|
||||
\medskip
|
||||
|
||||
Yet, stack unwinding (and thus debugging data) \emph{is not limited to
|
||||
debugging}.
|
||||
|
||||
Another common usage is profiling. A profiling tool, such as \prog{perf} under
|
||||
Linux, is used to measure and analyze in which functions a program spends its
|
||||
time, identify bottlenecks and find out which parts are critical to optimize.
|
||||
To do so, modern profilers pause the traced program at regular, short
|
||||
intervals, inspect their stack, and determine which function is currently being
|
||||
run. They also often perform a stack unwinding to determine the call path to
|
||||
this function, to determine which function indirectly takes time: \eg, a
|
||||
function \lstc{fct_a} can call both \lstc{fct_b} and \lstc{fct_c}, which are
|
||||
quite heavy; spend practically no time directly in \lstc{fct_a}, but spend a
|
||||
lot of time in calls to the other two functions that were made by \lstc{fct_a}.
|
||||
|
||||
Exception handling also requires a stack unwinding mechanism in most languages.
|
||||
Indeed, an exception is completely different from a \lstc{return}: while the
|
||||
latter returns to the previous function, the former can be caught by virtually
|
||||
any function in the call path, at any point of the function. It is thus
|
||||
necessary to be able to unwind frames, one by one, until a suitable
|
||||
\lstc{catch} block is found. The C++ language, for one, includes a
|
||||
stack-unwinding library similar to \prog{libunwind} in its runtime.
|
||||
|
||||
In both of these two previous cases, performance \emph{can} be a problem. In
|
||||
the latter, a slow unwinding directly impacts the overall program performance,
|
||||
particularly if a lot of exceptions are thrown and caught far away in their
|
||||
call path. In the former, profiling \emph{is} performance-heavy and often quite
|
||||
slow when analyzing large programs anyway.
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{DWARF format}
|
||||
|
||||
|
@ -168,10 +211,6 @@ drastically the unwinding process.
|
|||
\subsection{How big are FDEs?}
|
||||
\todo{}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{Unwinding usage and frequency}
|
||||
\todo{}
|
||||
|
||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||
\subsection{Unwinding state-of-the-art}
|
||||
\todo{}
|
||||
|
|
10
report/src/segfault/gdb_session
Normal file
10
report/src/segfault/gdb_session
Normal file
|
@ -0,0 +1,10 @@
|
|||
(gdb) backtrace
|
||||
#0 0x0000555555554625 in fct_b (m=0x5c) at segfault.c:5
|
||||
#1 0x0000555555554663 in fct_a (n=42) at segfault.c:10
|
||||
#2 0x0000555555554674 in main () at segfault.c:14
|
||||
(gdb) frame 1
|
||||
#1 0x0000555555554663 in fct_a (n=42) at segfault.c:10
|
||||
10 fct_b((int*)(some_fct_a_var + 8));
|
||||
(gdb) print some_fct_a_var
|
||||
$1 = 84
|
||||
|
17
report/src/segfault/segfault.c
Normal file
17
report/src/segfault/segfault.c
Normal file
|
@ -0,0 +1,17 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
|
||||
void fct_b(int* m) {
|
||||
printf("%l\n", *m);
|
||||
}
|
||||
|
||||
void fct_a(int n) {
|
||||
uintptr_t some_fct_a_var = n * 2;
|
||||
fct_b((int*)(some_fct_a_var + 8));
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
fct_a(42);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in a new issue