Adding some documentation

git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1962 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
unzner
2012-11-28 14:02:21 +00:00
parent 87ee9df37b
commit da3b2b8253
4 changed files with 255 additions and 0 deletions

View File

@ -0,0 +1,16 @@
62c62
< if (m_Data.getAddressSpace() == ANY_ADDR || m_Data.getAddressSpace() == address_space)
---
> if (m_Data.getAddressSpace() == ANY_ADDR || m_Data.getAddressSpace() == address_space) {
63a64
> }
86c87,91
< if (m_WatchInstrPtr == ANY_ADDR || m_WatchInstrPtr == pEv->getTriggerInstructionPointer())
---
> if (m_WatchInstrPtr == ANY_ADDR || m_WatchInstrPtr == pEv->getTriggerInstructionPointer()) {
> address_t address_space = pEv->getAddressSpace();
> if (address_space) {
> fprintf(stderr, "Got a match; address space: 0x%x\n", address_space);
> }
87a93
> }

View File

@ -0,0 +1,23 @@
195c195
< BPSingleListener bp(0, L4SYS_ADDRESS_SPACE);
---
> BPSingleListener bp(0, ANY_ADDR);
202,209c202,210
< bp.setWatchInstructionPointer(L4SYS_FUNC_ENTRY);
< simulator.addListenerAndResume(&bp);
<
< log << "test function entry reached, saving state" << endl;
< log << "EIP = " << hex << bp.getTriggerInstructionPointer() << " or "
< << simulator.getRegisterManager().getInstructionPointer()
< << endl;
< simulator.save(L4SYS_STATE_FOLDER);
---
> for (int i = 0; i < 500; i++) {
> bp.setWatchInstructionPointer(L4SYS_FUNC_ENTRY);
> simulator.addListenerAndResume(&bp);
> log << "test function entry reached" << endl;
> log << "EIP = " << hex << bp.getTriggerInstructionPointer() << " or "
> << simulator.getRegisterManager().getInstructionPointer()
> << endl;
> simulator.removeListener(&bp);
> }

Binary file not shown.

View File

@ -0,0 +1,216 @@
\documentclass[a4paper,10pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{hyphenat}
\tolerance 2414
\hbadness 2414
\emergencystretch 1.5em
\hfuzz 0.3pt
\widowpenalty=10000 % Hurenkinder
\clubpenalty=10000 % Schusterjungen
\vfuzz \hfuzz
\raggedbottom
\usepackage{hyperref}
%opening
\title{L4Sys User Manual}
\author{Martin Unzner (\href{mailto:munzner@os.inf.tu-dresden.de}{munzner@os.inf.tu-dresden.de})}
\begin{document}
\maketitle
\begin{abstract}
This document describes how to use the L4Sys experiment suite.
However, this is not a complete documentation. When in doubt,
please read the source code or contact me. Still, I would like
you to read this whole document before investigating further.
\end{abstract}
This is the user manual on the L4Sys generic system test framework.
It provides four experiment types: GPRFlip to simulate a bit flip
in a general purpose register, RATFlip to simulate a wrong association
in the register allocation table, IDCFLip to corrupt a specific instruction
and ALUInstrFlip to modify the behaviour of the arithmetic logic unit,
so that it performs a different calculation using the same parameters.
\section{Emulator Setup}
These experiments work with Bochs only. This is partly due to some
issues with timing --- as soon as a valid model of
time in the target emulator as well as an assembler/disassembler
functionality in the Fail* framework are established, I would recommend a
backend change, as Bochs' reliability is very limited.
To setup your system, first, you need a dedicated \texttt{bochsrc} file.
It has proven handy to have
a Bochs resource file or an independent Bochs instance with GUI enabled
for the initial testing, however the experiments are intended to be
conducted without graphical output.
\section{Client Setup}
All parameters of the L4Sys experiment client can be found
in the file \texttt{experimentInfo.hpp}. Normally, it should
not be necessary to change the program flow directly, however,
if something bothers you, you are always free to take a look
at \texttt{experiment.cc}, too.
\subsection{Constants}
Some values are constant throughout all steps of the preparation
and also when the workload program is run.
The most important constant is \verb+L4SYS_BOCHS_IPS+,
which has to be consistent with your \texttt{bochsrc} setting
and is used for several timely calculations in the client.
\subsection{Step 0: Determine the address space}
First, you need to find what are the addresses of the
start and end instructions of your
workload program. Therefore, you should use a
disassembler like \emph{objdump} or \emph{IDA Pro} and
set \verb+L4SYS_FUNC_ENTRY+ and \verb+L4SYS_FUNC_EXIT+
accordingly. \verb+L4SYS_NUMINSTR+
is determined automatically in a later preparation step and
can be ignored for now.
To test instructions that are run only in a specific address space,
L4Sys uses the address space filtering mechanism of Fail*.
If your fault injection campaign is not limited to a specific address space,
you may set \verb+L4SYS_ADDRESS_SPACE+ to \verb+ANY_ADDR+. Keep in mind that in
that case, your instruction addresses must be unique among all those
executed in the system, which in general is not the case.
Basically, there are two ways to find out the identifier of a certain
address space in Fail*: You can look up the value in
the emulator using a debugger. In the case of Bochs, you may want to
study
\href{http://bochs.sourceforge.net/doc/docbook/user/internal-debugger.html}{this page},
and, according to its instructions,
dump the content of the CR3 control register at the
beginning of your program.
You can also utilise the Fail* framework, which is easier and more reliable,
but as there is no real reason to include this ``feature'' in the framework,
in order to do so, you need to patch it. Namely,
\texttt{src/core/sal/Listener.cc} and
\texttt{src/experiments/l4-sys/experiment.cc}
need to be modified using the two patch files supplied alongside with this
manual in the current directory.
You should check the patch files for their release date and content:
In case the framework's
event handling structure has changed, the line numbers in
\texttt{Listener.cc} are incorrect,
and you need to apply the patch manually.
As soon as you have applied the patch, set \verb+PREPARATION_STEP+
to \texttt{1} in \texttt{experimentInfo.hpp} and recompile the framework.
Now start the experiment client (\texttt{fail-client}) in your
emulator directory, and
it will show you which address space is active whenever a
breakpoint triggers.
Ideally, you still have a graphical interface enabled to
monitor your system's progress and check if the breakpoints
are triggered at the right points in time.
When your program has reached the function entry point,
note the address space and exit the program simply by pressing Ctrl+C.
\subsection{Step 1: Save the initial state of the machine}
If you have modified the Fail* framework in Step 0,
you should now restore the original framework
data using \texttt{svn revert}.
Make sure \verb+PREPARATION_STEP+ is still set to \texttt{1}, and
you have set \verb+L4SYS_ADDRESS_SPACE+ accordingly.
Now recompile and execute the framework code again, this time with the graphical
user interface disabled. The experiment client runs until
\verb+L4SYS_FUNC_ENTRY+ is reached and then saves
the complete configuration.
\subsection{Step 2: Determine the instructions to execute}
For this part, it depends on how you want to conduct the injection
experiments. Setting \verb+L4SYS_FILTER_INSTRUCTIONS+
stores all instructions by default, and
enables the filter functionality to store only those
instructions that match the filter.
Each instruction in the trace requires
an address plus an unsigned breakpoint counter,
which means 8 bytes per instruction on a 32-bit system
and 12 bytes per instruction on a 64-bit system.
If \verb+L4SYS_FILTER_INSTRUCTIONS+ is not set, the instruction
to perform the fault injection at is determined by single-stepping
through the program from the beginning, which is quite slow.
I only recommend it for long programs, where a complete
instruction trace would require several hundred megabytes of data.
No matter which method you choose, the default implementation
of the campaign server reads the total instruction count
from \verb+L4SYS_NUMINSTR+. Thus, it is mandatory to set this
value to the number of instructions available.
To obtain this number and optionally the instruction trace,
set \verb+PREPARATION_STEP+ to \texttt{2} and recompile, then execute
the experiment client. You do not have to pass parameters to Bochs
any more, because the configuration is overwritten with the
state saved in step 1.
After the program has finished, you will get a summary on the
total of instructions executed.
If you have
\verb+L4SYS_FILTER_INSTRUCTIONS+ enabled, this is not the
value you look for; it merely claims how many
instructions have been processed at all.
To set \verb+L4SYS_NUMINSTR+ correctly, you need to look for the
number before the word \emph{accepted}, which points out how many
instructions have been accepted by the applied filter. Of course,
if no filtering is selected, these two figures should be equal.
Please contact me if that is not the case.
If \verb+L4SYS_FILTER_INSTRUCTIONS+ is disabled, you should
get a statistical output on how many of the instructions
were executed in userland and kernel space, respectively,
but the interesting figure in this case is of course the overall
sum of executed instructions.
\subsection{Step 3: Determine the correct output}
This is the easiest step: Set \verb+PREPARATION_STEP+ to \texttt{3},
recompile the client and execute it in the target directory.
It runs the complete program and logs the output. You can
check the resulting file (by default \texttt{golden.out}),
and if it does not comply with your expectations of a valid
run, you should correct the entry and exit point, the address space
or, in the worst case, your Bochs settings.
\section{Campaign Setup}
To setup the actual campaign, you need to edit \texttt{campaign.cc}.
The full language capabilities of \texttt{AspectC++} are at your hand to define
the course of your experiments; a sample covering all experiment
types at random is already provided. In the experiment client,
set \verb+PREPARATION_STEP+ to \texttt{0}, which means there is nothing more
to prepare.
After you have successfully compiled both programs, you need to
start both the campaign server (\texttt{l4-sys-server})
and the experiment client. By default, they should run on the
same machine, but you can adapt the \texttt{L4SysExperiment}
constructor in \texttt{experiment.cc} to connect the \texttt{JobClient}
to a remote server instead of \texttt{localhost}. Each experiment client processes
exactly one experiment and exits. To complete your campaign,
you should use the \texttt{client.sh} script in the \texttt{scripts}
subdirectory of Fail*.
\section{To Be Continued}
This is everything I consider important so far. If you still encounter
problems you may
contact me and I will try to set the record straight.
Happy experimenting! :)
\end{document}