Page MenuHomeFreeBSD

D25139.id73127.diff
No OneTemporary

D25139.id73127.diff

Index: head/en_US.ISO8859-1/books/developers-handbook/book.xml
===================================================================
--- head/en_US.ISO8859-1/books/developers-handbook/book.xml
+++ head/en_US.ISO8859-1/books/developers-handbook/book.xml
@@ -36,6 +36,8 @@
<year>2016</year>
<year>2017</year>
<year>2018</year>
+ <year>2019</year>
+ <year>2020</year>
<holder>The FreeBSD Documentation Project</holder>
</copyright>
Index: head/en_US.ISO8859-1/books/developers-handbook/tools/chapter.xml
===================================================================
--- head/en_US.ISO8859-1/books/developers-handbook/tools/chapter.xml
+++ head/en_US.ISO8859-1/books/developers-handbook/tools/chapter.xml
@@ -832,7 +832,7 @@
</question>
<answer>
- <para>Use <command>gdb</command> to analyze the core (see
+ <para>Use a debugger to analyze the core (see
<xref linkend="debugging"/>).</para>
</answer>
</qandaentry>
@@ -967,12 +967,12 @@
<para>Alternatively, you can create a core dump from
inside your program, by calling the
- <function>abort()</function> function. See the manual
+ <function>abort()</function> function. See the manual
page of &man.abort.3; to learn more.</para>
<para>If you want to create a core dump from outside your
program, but do not want the process to terminate, you
- can use the <command>gcore</command> program. See the
+ can use the <command>gcore</command> program. See the
manual page of &man.gcore.1; for more
information.</para>
</answer>
@@ -1325,75 +1325,389 @@
<title>Debugging</title>
<sect2>
- <title>The Debugger</title>
+ <title>Introduction to Available Debuggers</title>
- <para>The debugger that comes with FreeBSD is called
+ <para>Using a debugger allows running the program under more
+ controlled circumstances. Typically, it is possible to step
+ through the program a line at a time, inspect the value of
+ variables, change them, tell the debugger to run up to a
+ certain point and then stop, and so on. It is also possible
+ to attach to a program that is already running, or load a core
+ file to investigate why the program crashed. It is even
+ possible to debug the kernel, though that is a little trickier
+ than the user applications we will be discussing in this
+ section.</para>
+
+ <para>This section is intended to be a quick introduction to
+ using debuggers and does not cover specialized topics such as
+ debugging the kernel. For more information about that, refer
+ to <xref linkend="kerneldebug" />.</para>
+
+ <para>The standard debugger supplied with
+ &os;&nbsp;&rel121.current; is called <command>lldb</command>
+ (<application>LLVM debugger</application>). As it is part of
+ the standard installation for that release, there is no need
+ to do anything special to use it. It has good command help,
+ accessible via the <userinput>help</userinput> command, as
+ well as <link xlink:href="https://lldb.llvm.org/">a web
+ tutorial and documentation</link>.</para>
+
+ <note>
+ <para>The <command>lldb</command> command is available for
+ &os;&nbsp;&rel1.current; <link
+ xlink:href="&url.books.handbook;/ports-using.html">from
+ ports or packages</link> as
+ <package>devel/llvm</package>. This will install the
+ default version of lldb (currently 9.0).</para>
+ </note>
+
+ <para>The other debugger available with &os; is called
<command>gdb</command> (<application>GNU
- debugger</application>). You start it up by typing</para>
+ debugger</application>). Unlike lldb, it is not installed
+ by default on &os;&nbsp;&rel121.current;; to use it, <link
+ xlink:href="&url.books.handbook;/ports-using.html">install</link>
+ <package>devel/gdb</package> from ports or packages. The
+ version installed by default on &os;&nbsp;&rel1.current; is
+ old; instead, install <package>devel/gdb</package> there as
+ well. It has quite good on-line help, as well as a set of
+ info pages.</para>
+ <para>Which one to use is largely a matter of taste. If
+ familiar with one only, use that one. People familiar
+ with neither or both but wanting to use one from inside
+ <application>Emacs</application> will need to use
+ <command>gdb</command> as <command>lldb</command> is
+ unsupported by <application>Emacs</application>. Otherwise,
+ try both and see which one you prefer.</para>
+ </sect2>
+
+ <sect2>
+ <title>Using lldb</title>
+
+ <sect3>
+ <title>Starting lldb</title>
+
+ <para>Start up lldb by typing</para>
+
+ <screen>&prompt.user; <userinput>lldb -- <replaceable>progname</replaceable></userinput></screen>
+ </sect3>
+
+ <sect3>
+ <title>Running a Program with lldb</title>
+
+ <para>Compile the program with <option>-g</option> to get the
+ most out of using <command>lldb</command>. It will work
+ without, but will only display the name of the function
+ currently running, instead of the source code. If it
+ displays a line like:</para>
+
+ <screen>Breakpoint 1: where = temp`main, address = &hellip;</screen>
+
+ <para>(without an indication of source code filename and line
+ number) when setting a breakpoint, this means that the
+ program was not compiled with <option>-g</option>.</para>
+
+ <tip>
+ <para>Most <command>lldb</command> commands have shorter
+ forms that can be used instead. The longer forms are
+ used here for clarity.</para>
+ </tip>
+
+ <para>At the <command>lldb</command> prompt, type
+ <userinput>breakpoint set -n main</userinput>. This will
+ tell the debugger not to display the preliminary set-up code
+ in the program being run and to stop execution at the
+ beginning of the program's code. Now type
+ <userinput>process launch</userinput> to actually start the
+ program&mdash; it will start at the beginning of the set-up
+ code and then get stopped by the debugger when it calls
+ <function>main()</function>.</para>
+
+ <para>To step through the program a line at a time, type
+ <userinput>thread step-over</userinput>. When the program
+ gets to a function call, step into it by typing
+ <userinput>thread step-in</userinput>. Once in a function
+ call, return from it by typing
+ <userinput>thread step-out</userinput> or use
+ <userinput>up</userinput> and <userinput>down</userinput> to
+ take a quick look at the caller.</para>
+
+ <para>Here is a simple example of how to spot a mistake in a
+ program with <command>lldb</command>. This is our program
+ (with a deliberate mistake):</para>
+
+ <programlisting>#include &lt;stdio.h&gt;
+
+int bazz(int anint);
+
+main() {
+ int i;
+
+ printf("This is my program\n");
+ bazz(i);
+ return 0;
+}
+
+int bazz(int anint) {
+ printf("You gave me %d\n", anint);
+ return anint;
+}</programlisting>
+
+ <para>This program sets <symbol>i</symbol> to be
+ <literal>5</literal> and passes it to a function
+ <function>bazz()</function> which prints out the number we
+ gave it.</para>
+
+ <para>Compiling and running the program displays</para>
+
+ <screen>&prompt.user; <userinput>cc -g -o temp temp.c</userinput>
+&prompt.user; <userinput>./temp</userinput>
+This is my program
+anint = -5360</screen>
+
+ <para>That is not what was expected! Time to see what is going
+ on!</para>
+
+ <screen>&prompt.user; <userinput>lldb -- temp</userinput>
+(lldb) target create "temp"
+Current executable set to 'temp' (x86_64).
+(lldb) <userinput>breakpoint set -n main</userinput> <lineannotation>Skip the set-up code</lineannotation>
+Breakpoint 1: where = temp`main + 15 at temp.c:8:2, address = 0x00000000002012ef <lineannotation>lldb puts breakpoint at main()</lineannotation>
+(lldb) <userinput>process launch</userinput> <lineannotation>Run as far as main()</lineannotation>
+Process 9992 launching
+Process 9992 launched: '/home/pauamma/tmp/temp' (x86_64) <lineannotation>Program starts running</lineannotation>
+
+Process 9992 stopped
+* thread #1, name = 'temp', stop reason = breakpoint 1.1 <lineannotation>lldb stops at main()</lineannotation>
+ frame #0: 0x00000000002012ef temp`main at temp.c:8:2
+ 5 main() {
+ 6 int i;
+ 7
+-> 8 printf("This is my program\n"); <lineannotation>Indicates the line where it stopped</lineannotation>
+ 9 bazz(i);
+ 10 return 0;
+ 11 }
+(lldb) <userinput>thread step-over</userinput> <lineannotation>Go to next line</lineannotation>
+This is my program <lineannotation>Program prints out</lineannotation>
+Process 9992 stopped
+* thread #1, name = 'temp', stop reason = step over
+ frame #0: 0x0000000000201300 temp`main at temp.c:9:7
+ 6 int i;
+ 7
+ 8 printf("This is my program\n");
+-> 9 bazz(i);
+ 10 return 0;
+ 11 }
+ 12
+(lldb) <userinput>thread step-in</userinput> <lineannotation>step into bazz()</lineannotation>
+Process 9992 stopped
+* thread #1, name = 'temp', stop reason = step in
+ frame #0: 0x000000000020132b temp`bazz(anint=-5360) at temp.c:14:29 <lineannotation>lldb displays stack frame</lineannotation>
+ 11 }
+ 12
+ 13 int bazz(int anint) {
+-> 14 printf("You gave me %d\n", anint);
+ 15 return anint;
+ 16 }
+(lldb)</screen>
+
+ <para>Hang on a minute! How did <symbol>anint</symbol> get to
+ be <literal>-5360</literal>? Was it not set to
+ <literal>5</literal> in <function>main()</function>? Let us
+ move up to <function>main()</function> and have a
+ look.</para>
+
+ <screen>(lldb) <userinput>up</userinput> <lineannotation>Move up call stack</lineannotation>
+frame #1: 0x000000000020130b temp`main at temp.c:9:2 <lineannotation>lldb displays stack frame</lineannotation>
+ 6 int i;
+ 7
+ 8 printf("This is my program\n");
+-> 9 bazz(i);
+ 10 return 0;
+ 11 }
+ 12
+(lldb) <userinput>frame variable i</userinput> <lineannotation>Show us the value of i</lineannotation>
+(int) i = -5360 <lineannotation>lldb displays -5360</lineannotation></screen>
+
+ <para>Oh dear! Looking at the code, we forgot to initialize
+ <symbol>i</symbol>. We meant to put</para>
+
+ <programlisting><lineannotation>&hellip;</lineannotation>
+main() {
+ int i;
+
+ i = 5;
+ printf("This is my program\n");
+<lineannotation>&hellip;</lineannotation></programlisting>
+
+ <para>but we left the <literal>i=5;</literal> line out. As we
+ did not initialize <symbol>i</symbol>, it had whatever
+ number happened to be in that area of memory when the
+ program ran, which in this case happened to be
+ <literal>-5360</literal>.</para>
+
+ <note>
+ <para>The <command>lldb</command> command displays the stack
+ frame every time we go into or out of a function, even if
+ we are using <userinput>up</userinput> and
+ <userinput>down</userinput> to move around the call stack.
+ This shows the name of the function and the values of its
+ arguments, which helps us keep track of where we are and
+ what is going on. (The stack is a storage area where the
+ program stores information about the arguments passed to
+ functions and where to go when it returns from a function
+ call.)</para>
+ </note>
+ </sect3>
+
+ <sect3>
+ <title>Examining a Core File with lldb</title>
+
+ <para>A core file is basically a file which contains the
+ complete state of the process when it crashed. In
+ <quote>the good old days</quote>, programmers had to print
+ out hex listings of core files and sweat over machine code
+ manuals, but now life is a bit easier. Incidentally, under
+ &os; and other 4.4BSD systems, a core file is called
+ <filename><replaceable>progname</replaceable>.core</filename>
+ instead of just <filename>core</filename>, to make it
+ clearer which program a core file belongs to.</para>
+
+ <para>To examine a core file, specify the name of the core
+ file in addition to the program itself. Instead of starting
+ up <command>lldb</command> in the usual way, type
+ <userinput>lldb -c <replaceable>progname</replaceable>.core
+ -- <replaceable>progname</replaceable></userinput></para>
+
+ <para>The debugger will display something like this:</para>
+
+ <screen>&prompt.user; <userinput>lldb -c <filename><replaceable>progname</replaceable>.core</filename> -- <filename><replaceable>progname</replaceable></filename></userinput>
+(lldb) target create "<filename><replaceable>progname</replaceable></filename>" --core "<filename><replaceable>progname</replaceable></filename>.core"
+Core file '/home/pauamma/tmp/<filename><replaceable>progname</replaceable>.core</filename>' (x86_64) was loaded.
+(lldb)</screen>
+
+ <para>In this case, the program was called
+ <filename><replaceable>progname</replaceable></filename>, so
+ the core file is called
+ <filename><replaceable>progname</replaceable>.core</filename>.
+ The debugger does not display why the program crashed or
+ where. For this, use
+ <userinput>thread backtrace all</userinput>. This will also
+ show how the function where the program dumped core was
+ called.</para>
+
+ <screen>(lldb) <userinput>thread backtrace all</userinput>
+* thread #1, name = '<filename><replaceable>progname</replaceable></filename>', stop reason = signal SIGSEGV
+ * frame #0: 0x0000000000201347 <filename><replaceable>progname</replaceable></filename>`bazz(anint=5) at temp2.c:17:10
+ frame #1: 0x0000000000201312 <filename><replaceable>progname</replaceable></filename>`main at temp2.c:10:2
+ frame #2: 0x000000000020110f <filename><replaceable>progname</replaceable></filename>`_start(ap=&lt;unavailable&gt;, cleanup=&lt;unavailable&gt;) at crt1.c:76:7
+(lldb)</screen>
+
+ <para><literal>SIGSEGV</literal> indicates that the program
+ tried to access memory (run code or read/write data usually)
+ at a location that does not belong to it, but does not give
+ any specifics. For that, look at the source code at line 10
+ of file temp2.c, in <function>bazz()</function>. The
+ backtrace also says that in this case,
+ <function>bazz()</function> was called from
+ <function>main()</function>.</para>
+ </sect3>
+
+ <sect3>
+ <title>Attaching to a Running Program with lldb</title>
+
+ <para>One of the neatest features about
+ <command>lldb</command> is that it can attach to a program
+ that is already running. Of course, that requires
+ sufficient permissions to do so. A common problem is
+ stepping through a program that forks and wanting to trace
+ the child, but the debugger will only trace the
+ parent.</para>
+
+ <para>To do that, start up another <command>lldb</command>,
+ use <command>ps</command> to find the process ID for the
+ child, and do</para>
+
+ <screen>(lldb) <userinput>process attach -p <replaceable>pid</replaceable></userinput></screen>
+
+ <para>in <command>lldb</command>, and then debug as
+ usual.</para>
+
+ <para>For that to work well, the code that calls
+ <function>fork</function> to create the child needs to do
+ something like the following (courtesy of the
+ <command>gdb</command> info pages):</para>
+
+ <programlisting><lineannotation>&hellip;</lineannotation>
+if ((pid = fork()) &lt; 0) /* _Always_ check this */
+ error();
+else if (pid == 0) { /* child */
+ int PauseMode = 1;
+
+ while (PauseMode)
+ sleep(10); /* Wait until someone attaches to us */
+ <lineannotation>&hellip;</lineannotation>
+} else { /* parent */
+ <lineannotation>&hellip;</lineannotation></programlisting>
+
+ <para>Now all that is needed is to attach to the child, set
+ <symbol>PauseMode</symbol> to <literal>0</literal> with
+ <userinput>expr PauseMode = 0</userinput> and wait
+ for the <function>sleep()</function> call to return.</para>
+ </sect3>
+ </sect2>
+
+ <sect2>
+ <title>Using gdb</title>
+
+ <sect3>
+ <title>Starting gdb</title>
+
+ <para>Start up gdb by typing</para>
+
<screen>&prompt.user; <userinput>gdb <replaceable>progname</replaceable></userinput></screen>
<para>although many people prefer to run it inside
- <application>Emacs</application>. You can do this by:</para>
+ <application>Emacs</application>. To do this, type:</para>
<screen><userinput>M-x gdb RET <replaceable>progname</replaceable> RET</userinput></screen>
- <para>Using a debugger allows you to run the program under more
- controlled circumstances. Typically, you can step through the
- program a line at a time, inspect the value of variables,
- change them, tell the debugger to run up to a certain point
- and then stop, and so on. You can even attach to a program
- that is already running, or load a core file to investigate
- why the program crashed. It is even possible to debug the
- kernel, though that is a little trickier than the user
- applications we will be discussing in this section.</para>
-
- <para><command>gdb</command> has quite good on-line help, as
- well as a set of info pages, so this section will concentrate
- on a few of the basic commands.</para>
-
- <para>Finally, if you find its text-based command-prompt style
- off-putting, there is a graphical front-end for it
+ <para>Finally, for those finding its text-based command-prompt
+ style off-putting, there is a graphical front-end for it
(<package>devel/xxgdb</package>) in the Ports
Collection.</para>
- <para>This section is intended to be an introduction to using
- <command>gdb</command> and does not cover specialized topics
- such as debugging the kernel.</para>
- </sect2>
+ </sect3>
- <sect2>
- <title>Running a Program in the Debugger</title>
+ <sect3>
+ <title>Running a Program with gdb</title>
- <para>You will need to have compiled the program with
+ <para>Compile the program with
<option>-g</option> to get the most out of using
- <command>gdb</command>. It will work without, but you will
- only see the name of the function you are in, instead of the
- source code. If you see a line like:</para>
+ <command>gdb</command>. It will work without, but will
+ only display the name of the function currently running,
+ instead of the source code. A line like:</para>
<screen>&hellip; (no debugging symbols found) &hellip;</screen>
- <para>when <command>gdb</command> starts up, you will know that
- the program was not compiled with <option>-g</option>.</para>
+ <para>when <command>gdb</command> starts up means that the
+ program was not compiled with <option>-g</option>.</para>
<para>At the <command>gdb</command> prompt, type
<userinput>break main</userinput>. This will tell the
- debugger that you are not interested in watching the
- preliminary set-up code in the program being run, and that it
- should stop execution at the beginning of your code. Now type
- <userinput>run</userinput> to start the program&mdash;it will
- start at the beginning of the set-up code and then get stopped
- by the debugger when it calls <function>main()</function>.
- (If you have ever wondered where <function>main()</function>
- gets called from, now you know!).</para>
+ debugger to skip the preliminary set-up code in the program
+ being run and to stop execution at the beginning of the
+ program's code. Now type <userinput>run</userinput> to start
+ the program&mdash; it will start at the beginning of the
+ set-up code and then get stopped by the debugger when it calls
+ <function>main()</function>.</para>
- <para>You can now step through the program, a line at a time, by
- pressing <command>n</command>. If you get to a function call,
- you can step into it by pressing <command>s</command>. Once
- you are in a function call, you can return from stepping into
- a function call by pressing <command>f</command>. You can
- also use <command>up</command> and <command>down</command> to
- take a quick look at the caller.</para>
+ <para>To step through the program a line at a time, press
+ <command>n</command>. When at a function call, step into it
+ by pressing <command>s</command>. Once in a function call,
+ return from it by pressing <command>f</command>, or use
+ <command>up</command> and <command>down</command> to take
+ a quick look at the caller.</para>
<para>Here is a simple example of how to spot a mistake in a
program with <command>gdb</command>. This is our program
@@ -1421,7 +1735,7 @@
<function>bazz()</function> which prints out the number we
gave it.</para>
- <para>When we compile and run the program we get</para>
+ <para>Compiling and running the program displays</para>
<screen>&prompt.user; <userinput>cc -g -o temp temp.c</userinput>
&prompt.user; <userinput>./temp</userinput>
@@ -1449,7 +1763,7 @@
(gdb)</screen>
<para>Hang on a minute! How did <symbol>anint</symbol> get to be
- <literal>4231</literal>? Did we not we set it to be
+ <literal>4231</literal>? Was it not set to
<literal>5</literal> in <function>main()</function>? Let us
move up to <function>main()</function> and have a look.</para>
@@ -1476,26 +1790,26 @@
<literal>4231</literal>.</para>
<note>
- <para><command>gdb</command> displays the stack frame every
- time we go into or out of a function, even if we are using
- <command>up</command> and <command>down</command> to move
- around the call stack. This shows the name of the function
- and the values of its arguments, which helps us keep track
- of where we are and what is going on. (The stack is a
- storage area where the program stores information about the
- arguments passed to functions and where to go when it
- returns from a function call).</para>
- </note>
- </sect2>
+ <para>The <command>gdb</command> command displays the stack
+ frame every time we go into or out of a function, even if we
+ are using <command>up</command> and <command>down</command>
+ to move around the call stack. This shows the name of the
+ function and the values of its arguments, which helps us
+ keep track of where we are and what is going on. (The stack
+ is a storage area where the program stores information about
+ the arguments passed to functions and where to go when it
+ returns from a function call.)</para>
+ </note>
+ </sect3>
- <sect2>
- <title>Examining a Core File</title>
+ <sect3>
+ <title>Examining a Core File with gdb</title>
<para>A core file is basically a file which contains the
complete state of the process when it crashed. In <quote>the
good old days</quote>, programmers had to print out hex
listings of core files and sweat over machine code manuals,
- but now life is a bit easier. Incidentally, under FreeBSD and
+ but now life is a bit easier. Incidentally, under &os; and
other 4.4BSD systems, a core file is called
<filename><replaceable>progname</replaceable>.core</filename>
instead of just <filename>core</filename>, to make it clearer
@@ -1507,30 +1821,30 @@
<screen>(gdb) <userinput>core <replaceable>progname</replaceable>.core</userinput></screen>
- <para>If you are not in the same directory as the core file, you
- will have to do <userinput>dir /path/to/core/file</userinput>
- first.</para>
+ <para>If the core file is not in the current directory, type
+ <userinput>dir /path/to/core/file</userinput> first.</para>
- <para>You should see something like this:</para>
+ <para>The debugger should display something like this:</para>
- <screen>&prompt.user; <userinput>gdb a.out</userinput>
+ <screen>&prompt.user; <userinput>gdb <filename><replaceable>progname</replaceable></filename></userinput>
GDB is free software and you are welcome to distribute copies of it
under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.13 (i386-unknown-freebsd), Copyright 1994 Free Software Foundation, Inc.
-(gdb) <userinput>core a.out.core</userinput>
-Core was generated by `a.out'.
+(gdb) <userinput>core <filename><replaceable>progname</replaceable>.core</filename></userinput>
+Core was generated by `<filename><replaceable>progname</replaceable></filename>'.
Program terminated with signal 11, Segmentation fault.
Cannot access memory at address 0x7020796d.
#0 0x164a in bazz (anint=0x5) at temp.c:17
(gdb)</screen>
<para>In this case, the program was called
- <filename>a.out</filename>, so the core file is called
- <filename>a.out.core</filename>. We can see that the program
- crashed due to trying to access an area in memory that was not
- available to it in a function called
- <function>bazz</function>.</para>
+ <filename><replaceable>progname</replaceable></filename>, so
+ the core file is called
+ <filename><replaceable>progname</replaceable>.core</filename>.
+ We can see that the program crashed due to trying to access an
+ area in memory that was not available to it in a function
+ called <function>bazz</function>.</para>
<para>Sometimes it is useful to be able to see how a function
was called, as the problem could have occurred a long way up
@@ -1547,19 +1861,19 @@
<para>The <function>end()</function> function is called when a
program crashes; in this case, the <function>bazz()</function>
function was called from <function>main()</function>.</para>
- </sect2>
+ </sect3>
- <sect2>
- <title>Attaching to a Running Program</title>
+ <sect3>
+ <title>Attaching to a Running Program with gdb</title>
<para>One of the neatest features about <command>gdb</command>
is that it can attach to a program that is already running.
- Of course, that assumes you have sufficient permissions to do
- so. A common problem is when you are stepping through a
- program that forks, and you want to trace the child, but the
- debugger will only let you trace the parent.</para>
+ Of course, that requires sufficient permissions to do
+ so. A common problem is stepping through a program that forks
+ and wanting to trace the child, but the debugger will only
+ trace the parent.</para>
- <para>What you do is start up another <command>gdb</command>,
+ <para>To do that, start up another <command>gdb</command>,
use <command>ps</command> to find the process ID for the
child, and do</para>
@@ -1567,10 +1881,9 @@
<para>in <command>gdb</command>, and then debug as usual.</para>
- <para><quote>That is all very well,</quote> you are probably
- thinking, <quote>but by the time I have done that, the child
- process will be over the hill and far away</quote>. Fear
- not, gentle reader, here is how to do it (courtesy of the
+ <para>For that to work well, the code that calls
+ <function>fork</function> to create the child needs to do
+ something like the following (courtesy of the
<command>gdb</command> info pages):</para>
<programlisting><lineannotation>&hellip;</lineannotation>
@@ -1585,9 +1898,10 @@
} else { /* parent */
<lineannotation>&hellip;</lineannotation></programlisting>
- <para>Now all you have to do is attach to the child, set
+ <para>Now all that is needed is to attach to the child, set
<symbol>PauseMode</symbol> to <literal>0</literal>, and wait
for the <function>sleep()</function> call to return!</para>
+ </sect3>
</sect2>
</sect1>

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 12, 3:36 AM (4 h, 13 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
25192078
Default Alt Text
D25139.id73127.diff (26 KB)

Event Timeline