Multiple rephrasings
This commit is contained in:
parent
0c7350ff95
commit
4016b4f46c
2 changed files with 20 additions and 17 deletions
|
@ -32,7 +32,7 @@ computation~\cite{oakley2011exploiting}.
|
||||||
|
|
||||||
\subsection*{The research problem}
|
\subsection*{The research problem}
|
||||||
|
|
||||||
As debugging data can easily get heavy beyond reasonable if stored carelessly,
|
As debugging data can easily take an unreasonable space if stored carelessly,
|
||||||
the DWARF standard pays a great attention to data compactness and compression,
|
the DWARF standard pays a great attention to data compactness and compression,
|
||||||
and succeeds particularly well at it. But this, as always, is at the expense
|
and succeeds particularly well at it. But this, as always, is at the expense
|
||||||
of efficiency: accessing stack unwinding data for a particular program point
|
of efficiency: accessing stack unwinding data for a particular program point
|
||||||
|
@ -118,7 +118,7 @@ below. Yet, it supports the vast majority --~around $99.9$\ \%~-- of the cases
|
||||||
seen in the wild, and is decently robust compared to \prog{libunwind}, the
|
seen in the wild, and is decently robust compared to \prog{libunwind}, the
|
||||||
reference implementation. Indeed, corner cases occur often, and on a 27000
|
reference implementation. Indeed, corner cases occur often, and on a 27000
|
||||||
samples test, 885 failures were observed for \prog{libunwind}, against 1099 for
|
samples test, 885 failures were observed for \prog{libunwind}, against 1099 for
|
||||||
the compiled DWARF version.
|
the compiled DWARF version (see Section~\ref{ssec:timeperf}).
|
||||||
|
|
||||||
The implementation, however, as a few other limitations. It only supports the
|
The implementation, however, as a few other limitations. It only supports the
|
||||||
x86\_64 architecture, and relies to some extent on the Linux operating system.
|
x86\_64 architecture, and relies to some extent on the Linux operating system.
|
||||||
|
@ -132,7 +132,7 @@ virtually any operating system.
|
||||||
|
|
||||||
In most cases of everyday's life, a slow stack unwinding is not a problem, or
|
In most cases of everyday's life, a slow stack unwinding is not a problem, or
|
||||||
even an annoyance. Yet, having a 26 times speed-up on stack unwinding-heavy
|
even an annoyance. Yet, having a 26 times speed-up on stack unwinding-heavy
|
||||||
tasks, such as profiling, can be really useful to profile heavy programs,
|
tasks, such as profiling, can be really useful to profile large programs,
|
||||||
particularly if one wants to profile many times in order to analyze the impact
|
particularly if one wants to profile many times in order to analyze the impact
|
||||||
of multiple changes. It can also be useful for exception-heavy programs. Thus,
|
of multiple changes. It can also be useful for exception-heavy programs. Thus,
|
||||||
it might be interesting to implement a more stable version, and try to
|
it might be interesting to implement a more stable version, and try to
|
||||||
|
|
|
@ -179,9 +179,9 @@ traced program at regular, short intervals, inspect their stack, and determine
|
||||||
which function is currently being run. They also often perform a stack
|
which function is currently being run. They also often perform a stack
|
||||||
unwinding to determine the call path to this function, to determine which
|
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
|
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
|
\lstc{fct_b} and \lstc{fct_c}, which take a lot of time; spend practically no
|
||||||
directly in \lstc{fct_a}, but spend a lot of time in calls to the other two
|
time directly in \lstc{fct_a}, but spend a lot of time in calls to the other
|
||||||
functions that were made from \lstc{fct_a}.
|
two functions that were made from \lstc{fct_a}.
|
||||||
|
|
||||||
Exception handling also requires a stack unwinding mechanism in most languages.
|
Exception handling also requires a stack unwinding mechanism in most languages.
|
||||||
Indeed, an exception is completely different from a \lstinline{return}: while the
|
Indeed, an exception is completely different from a \lstinline{return}: while the
|
||||||
|
@ -375,13 +375,6 @@ distribution of FDE rows count. The histogram in
|
||||||
Figure~\ref{fig:fde_line_density} was generated on a random sample of around
|
Figure~\ref{fig:fde_line_density} was generated on a random sample of around
|
||||||
2000 ELF files present on an ArchLinux system.
|
2000 ELF files present on an ArchLinux system.
|
||||||
|
|
||||||
Most of the FDEs seem to be quite small, which only reflects that most
|
|
||||||
functions found in the wild are relatively small and do not particularly
|
|
||||||
allocate many times on the stack. Yet, the median value is at $8$ rows per FDE,
|
|
||||||
and the average is at $9.7$, which is already not that fast to unwind. Values
|
|
||||||
up to $50$ are not that uncommon, given some commonly used functions have such
|
|
||||||
large FDEs, and often end up in the call stack.
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\subsection{Unwinding state-of-the-art}
|
\subsection{Unwinding state-of-the-art}
|
||||||
|
|
||||||
|
@ -531,7 +524,7 @@ second frame will require loading the corresponding DWARF information.
|
||||||
|
|
||||||
The function is the following:
|
The function is the following:
|
||||||
|
|
||||||
\lstinputlisting[language=C]{src/dw_semantics/c_context.c}
|
\lstinputlisting[language=C]{src/dw_semantics/c_context.c}\label{lst:sem_c_ctx}
|
||||||
|
|
||||||
The translation of $\intermedlang$ as produced by the later-defined function
|
The translation of $\intermedlang$ as produced by the later-defined function
|
||||||
are then to be inserted in this context, where the comment states so.
|
are then to be inserted in this context, where the comment states so.
|
||||||
|
@ -743,7 +736,10 @@ In the unwind context from Listing~\ref{lst:unw_ctx}, the values of type
|
||||||
\lstc{flags} is a 8-bits value, indicating for each register whether it is
|
\lstc{flags} is a 8-bits value, indicating for each register whether it is
|
||||||
present or not in this context, plus an error bit, indicating whether an error
|
present or not in this context, plus an error bit, indicating whether an error
|
||||||
occurred during unwinding. Such errors can be due \eg{} to an unsupported
|
occurred during unwinding. Such errors can be due \eg{} to an unsupported
|
||||||
operation in the original DWARF\@.
|
operation in the original DWARF\@. This context differs from the one presented
|
||||||
|
in Section~\ref{lst:sem_c_ctx}, since the previous one was only an array of
|
||||||
|
values, and the one from the real implementation is more robust, in particular
|
||||||
|
by including an error flag by lack of $\bot$ value.
|
||||||
|
|
||||||
This generated data is stored in separate shared object files, which we call
|
This generated data is stored in separate shared object files, which we call
|
||||||
\ehelfs. It would have been possible to alter the original ELF file to embed
|
\ehelfs. It would have been possible to alter the original ELF file to embed
|
||||||
|
@ -997,7 +993,7 @@ computer has 32\,GB of RAM, and care was taken never to fill it and start
|
||||||
swapping.
|
swapping.
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\subsection{Measured time performance}
|
\subsection{Measured time performance}\label{ssec:timeperf}
|
||||||
|
|
||||||
A benchmarking of \ehelfs{} against the vanilla \prog{libunwind} was made using
|
A benchmarking of \ehelfs{} against the vanilla \prog{libunwind} was made using
|
||||||
the exact same methodology as in Section~\ref{ssec:bench_perf}, only linking
|
the exact same methodology as in Section~\ref{ssec:bench_perf}, only linking
|
||||||
|
@ -1057,6 +1053,14 @@ without using multiple cores to compile, the various shared objects needed to
|
||||||
run \prog{hackbench} --~that is, \prog{hackbench}, \prog{libc}, \prog{ld} and
|
run \prog{hackbench} --~that is, \prog{hackbench}, \prog{libc}, \prog{ld} and
|
||||||
\prog{libpthread}~-- are compiled in an overall time of $25.28$ seconds.
|
\prog{libpthread}~-- are compiled in an overall time of $25.28$ seconds.
|
||||||
|
|
||||||
|
The unwinding errors observed are hard to investigate, but are most probably
|
||||||
|
due to truncated stack records. Indeed, since \prog{perf} dumps the last $n$
|
||||||
|
bytes of the call stack (for a given $n$), and only keeps those for later
|
||||||
|
unwinding, large stacks leads to lost information when analyzing the results.
|
||||||
|
The difference between \ehelfs{} and the vanilla library could be due either to
|
||||||
|
unsupported DWARF instructions or registers, \prog{libdwarfpp} bugs or bugs in
|
||||||
|
the custom \prog{libunwind} implementation that were not spotted.
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
\subsection{Measured compactness}\label{ssec:results_size}
|
\subsection{Measured compactness}\label{ssec:results_size}
|
||||||
|
|
||||||
|
@ -1218,7 +1222,6 @@ It is also worth noting that of all the 4000 analyzed files, there are only 12
|
||||||
that contained all the unsupported expressions seen, and only 24 that contained
|
that contained all the unsupported expressions seen, and only 24 that contained
|
||||||
some unsupported instruction at all.
|
some unsupported instruction at all.
|
||||||
|
|
||||||
|
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
%%%% End main text content %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%% End main text content %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
|
||||||
|
|
Loading…
Reference in a new issue