Chapter 9: Tips and Techniques
Daemons and other background programs
Optimization Issues
Performance Issues
Daemons and other background programs
Normally starting a program under ZeroFault is quite simple: just
insert the zf command in front of the normal command line
for the program. However, using ZeroFault with daemon programs
(e.g. those started by init or inetd) and other
programs that are not started from the shell requires using one of
the following methods:
Optimization Issues
When the optimizer is turned on in the compiler, it sometimes places
load instructions ahead of the conditions that they are logically
dependent on. For instance in the following code fragment the optimizer
loads the value that s points to before it checks to see
if the pointer is NULL, even though the code explicitly says to
check the pointer first:
foo(char *s)
{
if (s) {
while (*s) {
if (*s == '\t')
*s = '\n';
++s;
}
}
}
This is the relevant assembler code generated by the optimizer:
0| 000000 ai. 34630000 2 LR_R gr3,cr0=gr3
5| 000004 lbz 88030000 1 L1Z gr0=(*)uchar(gr3,0)
5| 000008 cmpi 2C800000 2 C4 cr1=gr0,0
4| 00000C bcr 4D820020 0 BT CL.6,cr0,0x4/eq ,taken=50%
The ai instruction tests the value of the s pointer,
the lbz loads the byte pointed to by s, the cmpi
tests to see if the loaded byte is zero, and finally the bcr
branches to the end of the function if the pointer was NULL.
If this function is called with a NULL pointer, then ZeroFault
would normally generate an RNULL error. However,
the optimizer only generates code like this if it knows that nothing
destructive will result from it. For this reason, ZeroFault doesn't
generate USTKR or RNULL errors in modules that
have been optimized, to avoid generating false error messages.
The only automatic way that ZeroFault can infer that a module has been optimized
is if it doesn't contain line number debug information, such as
that generated by the -g compiler option. Therefore it
is suggested that you always use the -g flag without the
-O flag, and vice-versa.
The -g flag makes debug output much
more useful, but it does use more memory, especially when running
under ZeroFault (see below).
Performance Issues
Programs typically run slower under ZeroFault than natively.
The following steps may improve performance:
-
Only compile with debugging information (the -g compiler
flag) those modules that are important for debugging. The symbol
information that the compiler generates can take a lot of memory,
especially in C++ modules. Similarly, always optimize code that
will not figure prominently in your debugging efforts. It may
be much easier to rebuild specific object modules without optimization
than to suffer the performance impact of running large amounts of
unoptimized code.
- Only have one instantiation of ZeroFault running at a time on
a given system. Since the emulator may use a substantial amount
of paging space and CPU, having multiple instances running at
the same time could degrade system performance. This particularly
comes into play when a process forks many children, each of which
becomes a separate emulated process. Note that having multiple
user interfaces running can consume many resources, so running
zf with the -d none
flag and then running zf_ui
after the process exits can reduce the overall resource usage.