Introduce <qandaset> and friends.
un-<para>-wrap lists &prompt entities introduced PR: docs/14237 Submitted by: Neil Blakey-Milner <nbm@rucus.ru.ac.za>
This commit is contained in:
parent
12ef55c406
commit
d0fa9c9977
Notes:
svn2git
2020-12-08 03:00:23 +00:00
svn path=/head/; revision=5847
2 changed files with 440 additions and 230 deletions
en_US.ISO8859-1/articles/programming-tools
en_US.ISO_8859-1/articles/programming-tools
|
@ -1,4 +1,4 @@
|
|||
<!-- $FreeBSD: doc/en_US.ISO_8859-1/articles/programming-tools/article.sgml,v 1.7 1999/09/06 06:52:38 peter Exp $ -->
|
||||
<!-- $FreeBSD: doc/en_US.ISO_8859-1/articles/programming-tools/article.sgml,v 1.8 1999/10/04 22:04:28 jesusr Exp $ -->
|
||||
<!-- The FreeBSD Documentation Project -->
|
||||
|
||||
<!DOCTYPE ARTICLE PUBLIC "-//FreeBSD//DTD DocBook V3.1-Based Extension//EN">
|
||||
|
@ -118,13 +118,12 @@ interpreted languages. </para>
|
|||
|
||||
<para>To get one of these packages, all you need to do is to click on
|
||||
the hotlink for the package, then run
|
||||
<screen>$ <userinput>pkg_add <replaceable>package name</></userinput></screen>
|
||||
</para>
|
||||
<screen>&prompt.root; <userinput>pkg_add <replaceable>package name</></userinput></screen>
|
||||
|
||||
<para>as root. Obviously, you will need to have a fully functional FreeBSD
|
||||
2.1.0 or later system for the package to work!</para>
|
||||
|
||||
<para>
|
||||
<variablelist>
|
||||
<varlistentry><term><acronym>BASIC</></term>
|
||||
|
||||
|
@ -206,7 +205,6 @@ high enough level of abstraction to be used in research work.</para>
|
|||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
|
@ -309,13 +307,14 @@ steps 1 to 4—the others are referred to as
|
|||
<para>Fortunately, almost all this detail is hidden from you, as
|
||||
<command>cc</> is a front end that manages calling all these programs
|
||||
with the right arguments for you; simply typing
|
||||
<screen>$ <userinput>cc foobar.c</></screen></para>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>cc foobar.c</></screen>
|
||||
|
||||
<para>will cause <filename>foobar.c</> to be compiled by all the
|
||||
steps above. If you have more than one file to compile, just do
|
||||
something like
|
||||
<screen>$ <userinput>cc foo.c bar.c</></screen>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>cc foo.c bar.c</></screen>
|
||||
|
||||
<para>Note that the syntax checking is just that—checking the
|
||||
syntax. It will not check for any logical mistakes you may have made,
|
||||
|
@ -337,8 +336,8 @@ option, <command>cc</> will produce an executable called
|
|||
the mists of history.</para></footnote></para>
|
||||
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc foobar.c</> <lineannotation>executable is <filename>a.out</></>
|
||||
$ <userinput>cc -o foobar foobar.c</> <lineannotation>executable is <filename>foobar</></></screen>
|
||||
<screen>&prompt.user; <userinput>cc foobar.c</> <lineannotation>executable is <filename>a.out</></>
|
||||
&prompt.user; <userinput>cc -o foobar foobar.c</> <lineannotation>executable is <filename>foobar</></></screen>
|
||||
</informalexample>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -349,7 +348,7 @@ programs where you just want to check the syntax, or if you are using
|
|||
a <filename>Makefile</filename>.</para>
|
||||
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc -c foobar.c</userinput></screen>
|
||||
<screen>&prompt.user; <userinput>cc -c foobar.c</userinput></screen>
|
||||
</informalexample>
|
||||
|
||||
<para>This will produce an <firstterm>object file</> (not an
|
||||
|
@ -373,7 +372,7 @@ version</quote> without <option>-g</option> when you're satisfied it
|
|||
works properly.</para>
|
||||
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc -g foobar.c</userinput></screen>
|
||||
<screen>&prompt.user; <userinput>cc -g foobar.c</userinput></screen>
|
||||
</informalexample>
|
||||
|
||||
<para>This will produce a debug version of the
|
||||
|
@ -401,7 +400,7 @@ instance, the version of <command>cc</command> that comes with the
|
|||
version.</para>
|
||||
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc -O -o foobar foobar.c</userinput></screen>
|
||||
<screen>&prompt.user; <userinput>cc -O -o foobar foobar.c</userinput></screen>
|
||||
</informalexample>
|
||||
|
||||
<para>This will produce an optimised version of
|
||||
|
@ -461,7 +460,7 @@ program later to get it to work somewhere else—and who knows
|
|||
what you may be using in a few years time?</para>
|
||||
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc -Wall -ansi -pedantic -o foobar foobar.c</userinput></screen>
|
||||
<screen>&prompt.user; <userinput>cc -Wall -ansi -pedantic -o foobar foobar.c</userinput></screen>
|
||||
</informalexample>
|
||||
|
||||
<para>This will produce an executable <filename>foobar</filename>
|
||||
|
@ -490,7 +489,7 @@ the math library is <filename>libm.a</filename>, so you give
|
|||
last library on the command line.</para>
|
||||
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc -o foobar foobar.c -lm</userinput></screen>
|
||||
<screen>&prompt.user; <userinput>cc -o foobar foobar.c -lm</userinput></screen>
|
||||
</informalexample>
|
||||
|
||||
<para>This will link the math library functions into
|
||||
|
@ -505,9 +504,9 @@ instead of <command>cc</command>, which does this for you.
|
|||
on FreeBSD.</para>
|
||||
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc -o foobar foobar.cc -lg++</userinput> <lineannotation>For FreeBSD 2.1.6 and earlier</>
|
||||
$ <userinput>cc -o foobar foobar.cc -lstdc++</userinput> <lineannotation>For FreeBSD 2.2 and later</>
|
||||
$ <userinput>c++ -o foobar foobar.cc</userinput></screen>
|
||||
<screen>&prompt.user; <userinput>cc -o foobar foobar.cc -lg++</userinput> <lineannotation>For FreeBSD 2.1.6 and earlier</>
|
||||
&prompt.user; <userinput>cc -o foobar foobar.cc -lstdc++</userinput> <lineannotation>For FreeBSD 2.2 and later</>
|
||||
&prompt.user; <userinput>c++ -o foobar foobar.cc</userinput></screen>
|
||||
</informalexample>
|
||||
|
||||
<para>Each of these will both produce an executable
|
||||
|
@ -529,23 +528,31 @@ impunity!</para>
|
|||
<sect2>
|
||||
<title>Common <command>cc</command> Queries and Problems</title>
|
||||
|
||||
<para>Q. I am trying to write a program which uses the
|
||||
<qandaset>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>I am trying to write a program which uses the
|
||||
<function>sin()</function> function and I get an error like this.
|
||||
What does it mean?
|
||||
</para>
|
||||
<informalexample>
|
||||
<screen>/var/tmp/cc0143941.o: Undefined symbol `_sin' referenced from text segment</screen>
|
||||
</informalexample>
|
||||
</para>
|
||||
|
||||
<para>A. When using mathematical functions like
|
||||
</question>
|
||||
<answer>
|
||||
<para>When using mathematical functions like
|
||||
<function>sin()</function>, you have to tell <command>cc</command> to
|
||||
link in the math library, like so:
|
||||
link in the math library, like so:</para>
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc -o foobar foobar.c -lm</userinput></screen>
|
||||
</informalexample></para>
|
||||
|
||||
<para>Q. All right, I wrote this simple program to practice using
|
||||
<screen>&prompt.user; <userinput>cc -o foobar foobar.c -lm</userinput></screen>
|
||||
</informalexample>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>All right, I wrote this simple program to practice using
|
||||
<option>-lm</option>. All it does is raise 2.1 to the power of 6.
|
||||
</para>
|
||||
<informalexample>
|
||||
<programlisting>#include <stdio.h>
|
||||
|
||||
|
@ -557,31 +564,40 @@ int main() {
|
|||
return 0;
|
||||
}</programlisting>
|
||||
</informalexample>
|
||||
<para>
|
||||
and I compiled it as:
|
||||
</para>
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc temp.c -lm</userinput></screen>
|
||||
<screen>&prompt.user; <userinput>cc temp.c -lm</userinput></screen>
|
||||
</informalexample>
|
||||
<para>
|
||||
like you said I should, but I get this when I run it:
|
||||
</para>
|
||||
<informalexample>
|
||||
<screen>$ <userinput>./a.out</userinput>
|
||||
<screen>&prompt.user; <userinput>./a.out</userinput>
|
||||
2.1 ^ 6 = 1023.000000</screen>
|
||||
</informalexample>
|
||||
</para>
|
||||
|
||||
<para>This is <emphasis>not</emphasis> the right answer! What is
|
||||
going on?</para>
|
||||
|
||||
<para>A. When the compiler sees you call a function, it checks if it
|
||||
</question>
|
||||
<answer>
|
||||
<para>When the compiler sees you call a function, it checks if it
|
||||
has already seen a prototype for it. If it has not, it assumes the
|
||||
function returns an <type>int</type>, which is
|
||||
definitely not what you want here.</para>
|
||||
|
||||
<para>Q. So how do I fix this?</para>
|
||||
|
||||
<para>A. The prototypes for the mathematical functions are in
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>So how do I fix this?</para>
|
||||
</question>
|
||||
<answer>
|
||||
<para>The prototypes for the mathematical functions are in
|
||||
<filename>math.h</filename>. If you include this file, the compiler
|
||||
will be able to find the prototype and it will stop doing strange
|
||||
things to your calculation!
|
||||
</para>
|
||||
<informalexample>
|
||||
<programlisting>#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
@ -589,94 +605,125 @@ things to your calculation!
|
|||
int main() {
|
||||
...</programlisting>
|
||||
</informalexample>
|
||||
</para>
|
||||
|
||||
<para>After recompiling it as you did before, run it:
|
||||
</para>
|
||||
<informalexample>
|
||||
<screen>$ <userinput>./a.out</userinput>
|
||||
<screen>&prompt.user; <userinput>./a.out</userinput>
|
||||
2.1 ^ 6 = 85.766121</screen>
|
||||
</informalexample>
|
||||
</para>
|
||||
|
||||
<para>If you are using any of the mathematical functions,
|
||||
<emphasis>always</emphasis> include <filename>math.h</filename> and
|
||||
remember to link in the math library.</para>
|
||||
|
||||
<para>Q. I compiled a file called <filename>foobar.c</filename> and I
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>I compiled a file called <filename>foobar.c</filename> and I
|
||||
cannot find an executable called <filename>foobar</filename>. Where's
|
||||
it gone?</para>
|
||||
|
||||
<para>A. Remember, <command>cc</command> will call the executable
|
||||
</question>
|
||||
<answer>
|
||||
<para>Remember, <command>cc</command> will call the executable
|
||||
<filename>a.out</filename> unless you tell it differently. Use the
|
||||
<option>-o <replaceable>filename</replaceable></option> option:
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc -o foobar foobar.c</userinput></screen>
|
||||
</informalexample>
|
||||
</para>
|
||||
|
||||
<para>Q. OK, I have an executable called <filename>foobar</filename>,
|
||||
<informalexample>
|
||||
<screen>&prompt.user; <userinput>cc -o foobar foobar.c</userinput></screen>
|
||||
</informalexample>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>OK, I have an executable called <filename>foobar</filename>,
|
||||
I can see it when I run <command>ls</command>, but when I type in
|
||||
<command>foobar</command> at the command prompt it tells me there is
|
||||
no such file. Why can it not find it?</para>
|
||||
|
||||
<para>A. Unlike <trademark>MS-DOS</trademark>, Unix does not look in the
|
||||
</question>
|
||||
<answer>
|
||||
<para>Unlike <trademark>MS-DOS</trademark>, Unix does not look in the
|
||||
current directory when it is trying to find out which executable you
|
||||
want it to run, unless you tell it to. Either type
|
||||
<command>./foobar</command>, which means <quote>run the file called
|
||||
<filename>foobar</filename> in the current directory</quote>, or
|
||||
change your <systemitem class=environvar>PATH</systemitem>
|
||||
environment variable so that it looks something like
|
||||
</para>
|
||||
<informalexample>
|
||||
<screen>bin:/usr/bin:/usr/local/bin:.</screen>
|
||||
</informalexample>
|
||||
<para>
|
||||
The dot at the end means <quote>look in the current directory if it is not in
|
||||
any of the others</quote>.</para>
|
||||
|
||||
<para>Q. I called my executable <filename>test</filename>, but
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>I called my executable <filename>test</filename>, but
|
||||
nothing happens when I run it. What is going on?</para>
|
||||
|
||||
<para>A. Most Unix systems have a program called
|
||||
</question>
|
||||
<answer>
|
||||
<para>Most Unix systems have a program called
|
||||
<command>test</command> in <filename>/usr/bin</filename> and the
|
||||
shell is picking that one up before it gets to checking the current
|
||||
directory. Either type:
|
||||
</para>
|
||||
<informalexample>
|
||||
<screen>$ <userinput>./test</userinput></screen>
|
||||
<screen>&prompt.user; <userinput>./test</userinput></screen>
|
||||
</informalexample>
|
||||
<para>
|
||||
or choose a better name for your program!</para>
|
||||
|
||||
<para>Q. I compiled my program and it seemed to run all right at
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>I compiled my program and it seemed to run all right at
|
||||
first, then there was an error and it said something about <errorname>core
|
||||
dumped</errorname>. What does that mean?</para>
|
||||
|
||||
<para>A. The name <firstterm>core dump</firstterm> dates back to the
|
||||
</question>
|
||||
<answer>
|
||||
<para>The name <firstterm>core dump</firstterm> dates back to the
|
||||
very early days of Unix, when the machines used core memory for
|
||||
storing data. Basically, if the program failed under certain
|
||||
conditions, the system would write the contents of core memory to
|
||||
disk in a file called <filename>core</filename>, which the programmer
|
||||
could then pore over to find out what went wrong.</para>
|
||||
|
||||
<para>Q. Fascinating stuff, but what I am supposed to do now?</para>
|
||||
|
||||
<para>A. Use <command>gdb</command> to analyse the core (see <xref
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>Fascinating stuff, but what I am supposed to do now?</para>
|
||||
</question>
|
||||
<answer>
|
||||
<para>Use <command>gdb</command> to analyse the core (see <xref
|
||||
linkend="debugging">).</para>
|
||||
|
||||
<para>Q. When my program dumped core, it said something about a
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>When my program dumped core, it said something about a
|
||||
<errorname>segmentation fault</errorname>. What's that?</para>
|
||||
|
||||
<para>A. This basically means that your program tried to perform some sort
|
||||
</question>
|
||||
<answer>
|
||||
<para>This basically means that your program tried to perform some sort
|
||||
of illegal operation on memory; Unix is designed to protect the
|
||||
operating system and other programs from rogue programs.</para>
|
||||
|
||||
<para>Common causes for this are:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>Trying to write to a <symbol>NULL</symbol> pointer, eg
|
||||
</para>
|
||||
<programlisting>char *foo = NULL;
|
||||
strcpy(foo, "bang!");</programlisting>
|
||||
</para></listitem>
|
||||
</listitem>
|
||||
|
||||
<listitem><para>Using a pointer that hasn't been initialised, eg
|
||||
</para>
|
||||
<programlisting>char *foo;
|
||||
strcpy(foo, "bang!");</programlisting>
|
||||
<para>
|
||||
The pointer will have some random value that, with luck,
|
||||
will point into an area of memory that isn't available to
|
||||
your program and the kernel will kill your program before
|
||||
|
@ -686,51 +733,68 @@ data structures, causing the program to fail
|
|||
mysteriously.</para></listitem>
|
||||
|
||||
<listitem><para>Trying to access past the end of an array, eg
|
||||
</para>
|
||||
<programlisting>int bar[20];
|
||||
bar[27] = 6;</programlisting></para></listitem>
|
||||
bar[27] = 6;</programlisting></listitem>
|
||||
|
||||
<listitem><para> Trying to store something in read-only memory, eg
|
||||
</para>
|
||||
<programlisting>char *foo = "My string";
|
||||
strcpy(foo, "bang!");</programlisting>
|
||||
<para>
|
||||
Unix compilers often put string literals like
|
||||
<literal>"My string"</literal> into
|
||||
read-only areas of memory.</para></listitem>
|
||||
|
||||
<listitem><para>Doing naughty things with
|
||||
<function>malloc()</function> and <function>free()</function>, eg
|
||||
</para>
|
||||
<programlisting>char bar[80];
|
||||
free(bar);</programlisting>
|
||||
<para>
|
||||
or
|
||||
</para>
|
||||
<programlisting>char *foo = malloc(27);
|
||||
free(foo);
|
||||
free(foo);</programlisting>
|
||||
</para></listitem>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist></para>
|
||||
</itemizedlist>
|
||||
|
||||
<para>Making one of these mistakes will not always lead to an
|
||||
error, but they are always bad practice. Some systems and
|
||||
compilers are more tolerant than others, which is why programs
|
||||
that ran well on one system can crash when you try them on an
|
||||
another.</para>
|
||||
|
||||
<para>Q. Sometimes when I get a core dump it says <errorname>bus
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>Sometimes when I get a core dump it says <errorname>bus
|
||||
error</errorname>. It says in my Unix book that this means a hardware
|
||||
problem, but the computer still seems to be working. Is this
|
||||
true?</para>
|
||||
|
||||
<para>A. No, fortunately not (unless of course you really do have a hardware
|
||||
</question>
|
||||
<answer>
|
||||
<para>No, fortunately not (unless of course you really do have a hardware
|
||||
problem…). This is usually another way of saying that you
|
||||
accessed memory in a way you shouldn't have.</para>
|
||||
|
||||
<para>Q. This dumping core business sounds as though it could be quite
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>This dumping core business sounds as though it could be quite
|
||||
useful, if I can make it happen when I want to. Can I do this, or
|
||||
do I have to wait until there's an error?</para>
|
||||
|
||||
<para>A. Yes, just go to another console or xterm, do
|
||||
<screen>$ <userinput>ps</userinput></screen>
|
||||
</question>
|
||||
<answer>
|
||||
<para>Yes, just go to another console or xterm, do</para>
|
||||
<screen>&prompt.user; <userinput>ps</userinput></screen>
|
||||
<para>
|
||||
to find out the process ID of your program, and do
|
||||
<screen>$ <userinput>kill -ABRT <replaceable>pid</replaceable></userinput></screen>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>kill -ABRT <replaceable>pid</replaceable></userinput></screen>
|
||||
<para>
|
||||
where <parameter><replaceable>pid</replaceable></parameter> is the
|
||||
process ID you looked up.</para>
|
||||
|
||||
|
@ -738,6 +802,9 @@ process ID you looked up.</para>
|
|||
loop, for instance. If your program happens to trap
|
||||
<symbol>SIGABRT</symbol>, there are several other signals which have
|
||||
a similar effect.</para>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
</qandaset>
|
||||
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
@ -751,14 +818,18 @@ a similar effect.</para>
|
|||
|
||||
<para>When you're working on a simple program with only one or two source
|
||||
files, typing in
|
||||
<screen>$ <userinput>cc file1.c file2.c</userinput></screen>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>cc file1.c file2.c</userinput></screen>
|
||||
<para>
|
||||
is not too bad, but it quickly becomes very tedious when there are
|
||||
several files—and it can take a while to compile, too.</para>
|
||||
|
||||
<para>One way to get around this is to use object files and only recompile
|
||||
the source file if the source code has changed. So we could have
|
||||
something like:
|
||||
<screen>$ <userinput>cc file1.o file2.o</userinput> … <userinput>file37.c</userinput> &hellip</screen>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>cc file1.o file2.o</userinput> … <userinput>file37.c</userinput> &hellip</screen>
|
||||
<para>
|
||||
if we'd changed <filename>file37.c</filename>, but not any of the
|
||||
others, since the last time we compiled. This may speed up the
|
||||
compilation quite a bit, but doesn't solve the typing
|
||||
|
@ -805,8 +876,10 @@ are often used for documentation files like
|
|||
<title>Example of using <command>make</command></title>
|
||||
|
||||
<para>Here's a very simple make file:
|
||||
</para>
|
||||
<programlisting>foo: foo.c
|
||||
cc -o foo foo.c</programlisting>
|
||||
<para>
|
||||
It consists of two lines, a dependency line and a creation line.</para>
|
||||
|
||||
<para>The dependency line here consists of the name of the program
|
||||
|
@ -840,14 +913,17 @@ world</userinput> in the appropriate directory!</para>
|
|||
<para>Another useful property of makefiles is that the targets don't have
|
||||
to be programs. For instance, we could have a make file that looks
|
||||
like this:
|
||||
</para>
|
||||
<programlisting>foo: foo.c
|
||||
cc -o foo foo.c
|
||||
|
||||
install:
|
||||
cp foo /home/me</programlisting></para>
|
||||
cp foo /home/me</programlisting>
|
||||
|
||||
<para>We can tell make which target we want to make by typing:
|
||||
<screen>$ <userinput>make <replaceable>target</replaceable></userinput></screen>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>make <replaceable>target</replaceable></userinput></screen>
|
||||
<para>
|
||||
<command>make</command> will then only look at that target and ignore any
|
||||
others. For example, if we type <userinput>make foo</userinput> with the
|
||||
makefile above, make will ignore the <action>install</action> target.</para>
|
||||
|
@ -886,11 +962,11 @@ having to edit it.</para>
|
|||
BSD-based systems like FreeBSD come with some very powerful ones as
|
||||
part of the system. One very good example of this is the FreeBSD
|
||||
ports system. Here's the essential part of a typical ports
|
||||
<filename>Makefile</filename>:
|
||||
<filename>Makefile</filename>:</para>
|
||||
<programlisting>MASTER_SITES= ftp://freefall.cdrom.com/pub/FreeBSD/LOCAL_PORTS/
|
||||
DISTFILES= scheme-microcode+dist-7.3-freebsd.tgz
|
||||
|
||||
.include <bsd.port.mk></programlisting></para>
|
||||
.include <bsd.port.mk></programlisting>
|
||||
|
||||
<para>Now, if we go to the directory for this port and type
|
||||
<userinput>make</userinput>, the following happens:</para>
|
||||
|
@ -965,7 +1041,9 @@ have given you a base from which you can do this.</para>
|
|||
<para>The version of make that comes with FreeBSD is the <application>Berkeley
|
||||
make</application>; there is a tutorial for it in
|
||||
<filename>/usr/share/doc/psd/12.make</filename>. To view it, do
|
||||
<screen>$ <userinput>zmore paper.ascii.gz</userinput></screen>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>zmore paper.ascii.gz</userinput></screen>
|
||||
<para>
|
||||
in that directory.</para>
|
||||
|
||||
<para>Many applications in the ports use <application>GNU
|
||||
|
@ -979,7 +1057,9 @@ in its own right.</para>
|
|||
you will have to edit the <filename>dir</filename> file in the
|
||||
<filename>/usr/local/info</filename> directory to add an entry for
|
||||
it. This involves adding a line like
|
||||
</para>
|
||||
<programlisting> * Make: (make). The GNU Make utility.</programlisting>
|
||||
<para>
|
||||
to the file. Once you have done this, you can type
|
||||
<userinput>info</userinput> and then select
|
||||
<guimenuitem>make</guimenuitem> from the menu (or in
|
||||
|
@ -998,10 +1078,13 @@ i</userinput>).</para>
|
|||
<para>The debugger that comes with FreeBSD is called
|
||||
<command>gdb</command> (<application>GNU
|
||||
debugger</application>). You start it up by typing
|
||||
<screen>$ <userinput>gdb <replaceable>progname</replaceable></userinput></screen>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>gdb <replaceable>progname</replaceable></userinput></screen>
|
||||
<para>
|
||||
although most people prefer to run it inside
|
||||
<application>Emacs</application>. You can do this by:
|
||||
<screen><userinput>M-x gdb RET <replaceable>progname</replaceable> RET</userinput></screen></para>
|
||||
</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
|
||||
|
@ -1035,7 +1118,8 @@ debugging the kernel.</para>
|
|||
<command>gdb</command>. It will work without, but you'll only see the
|
||||
name of the function you're in, instead of the source code. If you
|
||||
see a line like:
|
||||
<screen>… (no debugging symbols found) …</screen>when
|
||||
</para>
|
||||
<screen>… (no debugging symbols found) …</screen><para>when
|
||||
<command>gdb</command> starts up, you'll know that the program wasn't
|
||||
compiled with the <option>-g</option> option.</para>
|
||||
|
||||
|
@ -1058,6 +1142,7 @@ pressing <command>f</command>. You can also use <command>up</command> and
|
|||
<para>Here's a simple example of how to spot a mistake in a program
|
||||
with <command>gdb</command>. This is our program (with a deliberate
|
||||
mistake):
|
||||
</para>
|
||||
<programlisting>#include <stdio.h>
|
||||
|
||||
int bazz(int anint);
|
||||
|
@ -1074,20 +1159,20 @@ int bazz(int anint) {
|
|||
printf("You gave me %d\n", anint);
|
||||
return anint;
|
||||
}</programlisting>
|
||||
</para>
|
||||
|
||||
<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>When we compile and run the program we get
|
||||
<screen>$ <userinput>cc -g -o temp temp.c</userinput>
|
||||
$ <userinput>./temp</userinput>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>cc -g -o temp temp.c</userinput>
|
||||
&prompt.user; <userinput>./temp</userinput>
|
||||
This is my program
|
||||
anint = 4231</screen></para>
|
||||
anint = 4231</screen>
|
||||
|
||||
<para>That wasn't what we expected! Time to see what's going
|
||||
on!<screen>$ <userinput>gdb temp</userinput>
|
||||
on!</para><screen>&prompt.user; <userinput>gdb temp</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.
|
||||
|
@ -1102,7 +1187,7 @@ Breakpoint 1, main () at temp.c:9 <lineannotation><command>gdb</command> stops
|
|||
This is my program <lineannotation>Program prints out</>
|
||||
(gdb) <userinput>s</> <lineannotation>step into <function>bazz()</></>
|
||||
bazz (anint=4231) at temp.c:17 <lineannotation><command>gdb</command> displays stack frame</>
|
||||
(gdb)</screen></para>
|
||||
(gdb)</screen>
|
||||
|
||||
|
||||
<para>Hang on a minute! How did <symbol>anint</symbol> get to be
|
||||
|
@ -1110,12 +1195,15 @@ bazz (anint=4231) at temp.c:17 <lineannotation><command>gdb</command> displays
|
|||
in <function>main()</function>? Let's move up to
|
||||
<function>main()</function> and have a look.</para>
|
||||
|
||||
<para><screen>(gdb) <userinput>up</> <lineannotation>Move up call stack</>
|
||||
<screen>(gdb) <userinput>up</> <lineannotation>Move up call stack</>
|
||||
#1 0x1625 in main () at temp.c:11 <lineannotation><command>gdb</command> displays stack frame</>
|
||||
(gdb) <userinput>p i</> <lineannotation>Show us the value of <symbol>i</></>
|
||||
$1 = 4231 <lineannotation><command>gdb</command> displays <literal>4231</></></screen>
|
||||
$1 = 4231 <lineannotation><command>gdb</command> displays <literal>4231</></>
|
||||
</screen>
|
||||
<para>
|
||||
Oh dear! Looking at the code, we forgot to initialise
|
||||
<symbol>i</symbol>. We meant to put
|
||||
</para>
|
||||
<programlisting><lineannotation>…</>
|
||||
main() {
|
||||
int i;
|
||||
|
@ -1123,6 +1211,7 @@ main() {
|
|||
i = 5;
|
||||
printf("This is my program\n");
|
||||
<lineannotation>&hellip</></programlisting>
|
||||
<para>
|
||||
but we left the <literal>i=5;</literal> line out. As we didn't
|
||||
initialise <symbol>i</symbol>, it had whatever number happened to be
|
||||
in that area of memory when the program ran, which in this case
|
||||
|
@ -1154,12 +1243,15 @@ file belongs to.</para>
|
|||
<para>To examine a core file, start up <command>gdb</command> in the
|
||||
usual way. Instead of typing <command>break</command> or
|
||||
<command>run</command>, type
|
||||
</para>
|
||||
<screen>(gdb) <userinput>core <replaceable>progname</replaceable>.core</userinput></screen>
|
||||
<para>
|
||||
If you're not in the same directory as the core file, you'll have to
|
||||
do <userinput>dir /path/to/core/file</userinput> first.</para>
|
||||
|
||||
<para>You should see something like this:
|
||||
<screen>$ <userinput>gdb a.out</userinput>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>gdb a.out</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.
|
||||
|
@ -1169,7 +1261,7 @@ Core was generated by `a.out'.
|
|||
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>
|
||||
(gdb)</screen>
|
||||
|
||||
<para>In this case, the program was called
|
||||
<filename>a.out</filename>, so the core file is called
|
||||
|
@ -1182,11 +1274,12 @@ called, as the problem could have occurred a long way up the call
|
|||
stack in a complex program. The <command>bt</command> command causes
|
||||
<command>gdb</command> to print out a back-trace of the call
|
||||
stack:
|
||||
</para>
|
||||
<screen>(gdb) <userinput>bt</userinput>
|
||||
#0 0x164a in bazz (anint=0x5) at temp.c:17
|
||||
#1 0xefbfd888 in end ()
|
||||
#2 0x162c in main () at temp.c:11
|
||||
(gdb)</screen>The <function>end()</function> function is called when
|
||||
(gdb)</screen><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>
|
||||
|
||||
|
@ -1204,13 +1297,15 @@ the parent.</para>
|
|||
|
||||
<para>What you do is start up another <command>gdb</command>, use
|
||||
<command>ps</command> to find the process ID for the child, and
|
||||
do<screen>(gdb) <userinput>attach <replaceable>pid</replaceable></userinput></screen>
|
||||
do</para><screen>(gdb) <userinput>attach <replaceable>pid</replaceable></userinput></screen>
|
||||
<para>
|
||||
in <command>gdb</command>, and then debug as usual.</para>
|
||||
|
||||
<para><quote>That's all very well,</quote> you're probably thinking,
|
||||
<quote>but by the time I've done that, the child process will be over
|
||||
the hill and far away</quote>. Fear not, gentle reader, here's how to
|
||||
do it (courtesy of the <command>gdb</command> info pages):
|
||||
</para>
|
||||
<screen><lineannotation>&hellip</lineannotation>
|
||||
if ((pid = fork()) < 0) /* _Always_ check this */
|
||||
error();
|
||||
|
@ -1222,6 +1317,7 @@ else if (pid == 0) { /* child */
|
|||
<lineannotation>&hellip</lineannotation>
|
||||
} else { /* parent */
|
||||
<lineannotation>&hellip</lineannotation></screen>
|
||||
<para>
|
||||
Now all you have to do is attach to the child, set
|
||||
<symbol>PauseMode</symbol> to <literal>0</literal>, and
|
||||
wait for the <function>sleep()</function> call to return!</para>
|
||||
|
@ -1259,6 +1355,7 @@ only to log out.</para>
|
|||
|
||||
<para>It's impossible even to summarise everything Emacs can do here, but
|
||||
here are some of the features of interest to developers:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
|
||||
<listitem><para>Very powerful editor, allowing search-and-replace on
|
||||
|
@ -1289,7 +1386,7 @@ program.</para></listitem>
|
|||
<listitem><para>You can read Usenet news and mail while your program
|
||||
is compiling.</para></listitem>
|
||||
|
||||
</itemizedlist>And doubtless many more that I've overlooked.</para>
|
||||
</itemizedlist><para>And doubtless many more that I've overlooked.</para>
|
||||
|
||||
<para>Emacs can be installed on FreeBSD using <ulink
|
||||
URL="../../ports/editors.html">the Emacs
|
||||
|
@ -1386,7 +1483,6 @@ it's already running; it will read the commands from the file and
|
|||
<para>Unfortunately, there's far too much here to explain it in detail;
|
||||
however there are one or two points worth mentioning.</para>
|
||||
|
||||
<para>
|
||||
<itemizedlist>
|
||||
|
||||
<listitem><para>Everything beginning with a <literal>;</> is a
|
||||
|
@ -1423,7 +1519,9 @@ line.</para></listitem>
|
|||
<listitem><para> We enable Emacs's ability to act as a server, so
|
||||
that if you're doing something outside Emacs and you want to edit a
|
||||
file, you can just type in
|
||||
<screen>$ <userinput>emacsclient <replaceable>filename</replaceable></userinput></screen>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>emacsclient <replaceable>filename</replaceable></userinput></screen>
|
||||
<para>
|
||||
and then you can edit the file in your Emacs!<footnote><para>Many
|
||||
Emacs users set their <systemitem
|
||||
class=environvar>EDITOR</systemitem> environment to
|
||||
|
@ -1431,11 +1529,10 @@ class=environvar>EDITOR</systemitem> environment to
|
|||
to edit a file.</para></footnote></para></listitem>
|
||||
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>A sample <filename>.emacs</filename> file</title>
|
||||
<screen>;; -*-Emacs-Lisp-*-
|
||||
<programlisting>;; -*-Emacs-Lisp-*-
|
||||
|
||||
;; This file is designed to be re-evaled; use the variable first-time
|
||||
;; to avoid any problems with this.
|
||||
|
@ -1509,9 +1606,9 @@ to edit a file.</para></footnote></para></listitem>
|
|||
(autoload 'ediff-buffers "ediff" "Intelligent Emacs interface to diff" t)
|
||||
(autoload 'ediff-files "ediff" "Intelligent Emacs interface to diff" t)
|
||||
(autoload 'ediff-files-remote "ediff"
|
||||
"Intelligent Emacs interface to diff") </screen>
|
||||
"Intelligent Emacs interface to diff")
|
||||
|
||||
<screen>(if first-time
|
||||
(if first-time
|
||||
(setq auto-mode-alist
|
||||
(append '(("\\.cpp$" . c++-mode)
|
||||
("\\.hpp$" . c++-mode)
|
||||
|
@ -1613,9 +1710,9 @@ in font-lock-auto-mode-list"
|
|||
(defun previous-error (n)
|
||||
"Visit previous compilation error message and corresponding source code."
|
||||
(interactive "p")
|
||||
(next-error (- n)))</screen>
|
||||
(next-error (- n)))
|
||||
|
||||
<screen>;; Misc...
|
||||
;; Misc...
|
||||
(transient-mark-mode 1)
|
||||
(setq mark-even-if-inactive t)
|
||||
(setq visible-bell nil)
|
||||
|
@ -1716,7 +1813,7 @@ in font-lock-auto-mode-list"
|
|||
|
||||
;; All done
|
||||
(message "All done, %s%s" (user-login-name) ".")
|
||||
</screen>
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
</sect2>
|
||||
|
@ -1735,16 +1832,20 @@ comes with any files that tell Emacs about the language. These
|
|||
usually end in <filename>.el</filename>, short for <quote>Emacs
|
||||
Lisp</quote>. For example, if whizbang is a FreeBSD
|
||||
port, we can locate these files by doing
|
||||
<screen>$ <userinput>find /usr/ports/lang/whizbang -name "*.el" -print</userinput></screen>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>find /usr/ports/lang/whizbang -name "*.el" -print</userinput></screen>
|
||||
<para>
|
||||
and install them by copying them into the Emacs site Lisp directory. On
|
||||
FreeBSD 2.1.0-RELEASE, this is
|
||||
<filename>/usr/local/share/emacs/site-lisp</filename>.</para>
|
||||
|
||||
<para>So for example, if the output from the find command was
|
||||
<screen>/usr/ports/lang/whizbang/work/misc/whizbang.el</screen>
|
||||
we would do
|
||||
<screen>$ <userinput>cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp</userinput></screen>
|
||||
</para>
|
||||
<screen>/usr/ports/lang/whizbang/work/misc/whizbang.el</screen>
|
||||
<para>
|
||||
we would do
|
||||
</para>
|
||||
<screen>&prompt.root; <userinput>cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp</userinput></screen>
|
||||
|
||||
<para>Next, we need to decide what extension whizbang source files
|
||||
have. Let's say for the sake of argument that they all end in
|
||||
|
@ -1755,11 +1856,13 @@ use the information in <filename>whizbang.el</filename>.</para>
|
|||
<para>Find the <symbol>auto-mode-alist entry</symbol> in
|
||||
<filename>.emacs</filename> and add a line for whizbang, such
|
||||
as:
|
||||
</para>
|
||||
<programlisting><lineannotation>…</>
|
||||
("\\.lsp$" . lisp-mode)
|
||||
("\\.wiz$" . whizbang-mode)
|
||||
("\\.scm$" . scheme-mode)
|
||||
<lineannotation>…</></programlisting>
|
||||
<para>
|
||||
This means that Emacs will automatically go into
|
||||
<function>whizbang-mode</function> when you edit a file ending in
|
||||
<filename>.wiz</filename>.</para>
|
||||
|
@ -1767,10 +1870,12 @@ This means that Emacs will automatically go into
|
|||
<para>Just below this, you'll find the
|
||||
<symbol>font-lock-auto-mode-list</symbol> entry. Add
|
||||
<function>whizbang-mode</function> to it like so:
|
||||
</para>
|
||||
<programlisting>;; Auto font lock mode
|
||||
(defvar font-lock-auto-mode-list
|
||||
(list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'whizbang-mode 'lisp-mode 'perl-mode 'scheme-mode)
|
||||
"List of modes to always start in font-lock-mode")</programlisting>
|
||||
<para>
|
||||
This means that Emacs will always enable
|
||||
<function>font-lock-mode</function> (ie syntax highlighting) when
|
||||
editing a <filename>.wiz</filename> file.</para>
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<!-- $FreeBSD: doc/en_US.ISO_8859-1/articles/programming-tools/article.sgml,v 1.7 1999/09/06 06:52:38 peter Exp $ -->
|
||||
<!-- $FreeBSD: doc/en_US.ISO_8859-1/articles/programming-tools/article.sgml,v 1.8 1999/10/04 22:04:28 jesusr Exp $ -->
|
||||
<!-- The FreeBSD Documentation Project -->
|
||||
|
||||
<!DOCTYPE ARTICLE PUBLIC "-//FreeBSD//DTD DocBook V3.1-Based Extension//EN">
|
||||
|
@ -118,13 +118,12 @@ interpreted languages. </para>
|
|||
|
||||
<para>To get one of these packages, all you need to do is to click on
|
||||
the hotlink for the package, then run
|
||||
<screen>$ <userinput>pkg_add <replaceable>package name</></userinput></screen>
|
||||
</para>
|
||||
<screen>&prompt.root; <userinput>pkg_add <replaceable>package name</></userinput></screen>
|
||||
|
||||
<para>as root. Obviously, you will need to have a fully functional FreeBSD
|
||||
2.1.0 or later system for the package to work!</para>
|
||||
|
||||
<para>
|
||||
<variablelist>
|
||||
<varlistentry><term><acronym>BASIC</></term>
|
||||
|
||||
|
@ -206,7 +205,6 @@ high enough level of abstraction to be used in research work.</para>
|
|||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</para>
|
||||
|
||||
</sect2>
|
||||
|
||||
|
@ -309,13 +307,14 @@ steps 1 to 4—the others are referred to as
|
|||
<para>Fortunately, almost all this detail is hidden from you, as
|
||||
<command>cc</> is a front end that manages calling all these programs
|
||||
with the right arguments for you; simply typing
|
||||
<screen>$ <userinput>cc foobar.c</></screen></para>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>cc foobar.c</></screen>
|
||||
|
||||
<para>will cause <filename>foobar.c</> to be compiled by all the
|
||||
steps above. If you have more than one file to compile, just do
|
||||
something like
|
||||
<screen>$ <userinput>cc foo.c bar.c</></screen>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>cc foo.c bar.c</></screen>
|
||||
|
||||
<para>Note that the syntax checking is just that—checking the
|
||||
syntax. It will not check for any logical mistakes you may have made,
|
||||
|
@ -337,8 +336,8 @@ option, <command>cc</> will produce an executable called
|
|||
the mists of history.</para></footnote></para>
|
||||
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc foobar.c</> <lineannotation>executable is <filename>a.out</></>
|
||||
$ <userinput>cc -o foobar foobar.c</> <lineannotation>executable is <filename>foobar</></></screen>
|
||||
<screen>&prompt.user; <userinput>cc foobar.c</> <lineannotation>executable is <filename>a.out</></>
|
||||
&prompt.user; <userinput>cc -o foobar foobar.c</> <lineannotation>executable is <filename>foobar</></></screen>
|
||||
</informalexample>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -349,7 +348,7 @@ programs where you just want to check the syntax, or if you are using
|
|||
a <filename>Makefile</filename>.</para>
|
||||
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc -c foobar.c</userinput></screen>
|
||||
<screen>&prompt.user; <userinput>cc -c foobar.c</userinput></screen>
|
||||
</informalexample>
|
||||
|
||||
<para>This will produce an <firstterm>object file</> (not an
|
||||
|
@ -373,7 +372,7 @@ version</quote> without <option>-g</option> when you're satisfied it
|
|||
works properly.</para>
|
||||
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc -g foobar.c</userinput></screen>
|
||||
<screen>&prompt.user; <userinput>cc -g foobar.c</userinput></screen>
|
||||
</informalexample>
|
||||
|
||||
<para>This will produce a debug version of the
|
||||
|
@ -401,7 +400,7 @@ instance, the version of <command>cc</command> that comes with the
|
|||
version.</para>
|
||||
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc -O -o foobar foobar.c</userinput></screen>
|
||||
<screen>&prompt.user; <userinput>cc -O -o foobar foobar.c</userinput></screen>
|
||||
</informalexample>
|
||||
|
||||
<para>This will produce an optimised version of
|
||||
|
@ -461,7 +460,7 @@ program later to get it to work somewhere else—and who knows
|
|||
what you may be using in a few years time?</para>
|
||||
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc -Wall -ansi -pedantic -o foobar foobar.c</userinput></screen>
|
||||
<screen>&prompt.user; <userinput>cc -Wall -ansi -pedantic -o foobar foobar.c</userinput></screen>
|
||||
</informalexample>
|
||||
|
||||
<para>This will produce an executable <filename>foobar</filename>
|
||||
|
@ -490,7 +489,7 @@ the math library is <filename>libm.a</filename>, so you give
|
|||
last library on the command line.</para>
|
||||
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc -o foobar foobar.c -lm</userinput></screen>
|
||||
<screen>&prompt.user; <userinput>cc -o foobar foobar.c -lm</userinput></screen>
|
||||
</informalexample>
|
||||
|
||||
<para>This will link the math library functions into
|
||||
|
@ -505,9 +504,9 @@ instead of <command>cc</command>, which does this for you.
|
|||
on FreeBSD.</para>
|
||||
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc -o foobar foobar.cc -lg++</userinput> <lineannotation>For FreeBSD 2.1.6 and earlier</>
|
||||
$ <userinput>cc -o foobar foobar.cc -lstdc++</userinput> <lineannotation>For FreeBSD 2.2 and later</>
|
||||
$ <userinput>c++ -o foobar foobar.cc</userinput></screen>
|
||||
<screen>&prompt.user; <userinput>cc -o foobar foobar.cc -lg++</userinput> <lineannotation>For FreeBSD 2.1.6 and earlier</>
|
||||
&prompt.user; <userinput>cc -o foobar foobar.cc -lstdc++</userinput> <lineannotation>For FreeBSD 2.2 and later</>
|
||||
&prompt.user; <userinput>c++ -o foobar foobar.cc</userinput></screen>
|
||||
</informalexample>
|
||||
|
||||
<para>Each of these will both produce an executable
|
||||
|
@ -529,23 +528,31 @@ impunity!</para>
|
|||
<sect2>
|
||||
<title>Common <command>cc</command> Queries and Problems</title>
|
||||
|
||||
<para>Q. I am trying to write a program which uses the
|
||||
<qandaset>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>I am trying to write a program which uses the
|
||||
<function>sin()</function> function and I get an error like this.
|
||||
What does it mean?
|
||||
</para>
|
||||
<informalexample>
|
||||
<screen>/var/tmp/cc0143941.o: Undefined symbol `_sin' referenced from text segment</screen>
|
||||
</informalexample>
|
||||
</para>
|
||||
|
||||
<para>A. When using mathematical functions like
|
||||
</question>
|
||||
<answer>
|
||||
<para>When using mathematical functions like
|
||||
<function>sin()</function>, you have to tell <command>cc</command> to
|
||||
link in the math library, like so:
|
||||
link in the math library, like so:</para>
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc -o foobar foobar.c -lm</userinput></screen>
|
||||
</informalexample></para>
|
||||
|
||||
<para>Q. All right, I wrote this simple program to practice using
|
||||
<screen>&prompt.user; <userinput>cc -o foobar foobar.c -lm</userinput></screen>
|
||||
</informalexample>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>All right, I wrote this simple program to practice using
|
||||
<option>-lm</option>. All it does is raise 2.1 to the power of 6.
|
||||
</para>
|
||||
<informalexample>
|
||||
<programlisting>#include <stdio.h>
|
||||
|
||||
|
@ -557,31 +564,40 @@ int main() {
|
|||
return 0;
|
||||
}</programlisting>
|
||||
</informalexample>
|
||||
<para>
|
||||
and I compiled it as:
|
||||
</para>
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc temp.c -lm</userinput></screen>
|
||||
<screen>&prompt.user; <userinput>cc temp.c -lm</userinput></screen>
|
||||
</informalexample>
|
||||
<para>
|
||||
like you said I should, but I get this when I run it:
|
||||
</para>
|
||||
<informalexample>
|
||||
<screen>$ <userinput>./a.out</userinput>
|
||||
<screen>&prompt.user; <userinput>./a.out</userinput>
|
||||
2.1 ^ 6 = 1023.000000</screen>
|
||||
</informalexample>
|
||||
</para>
|
||||
|
||||
<para>This is <emphasis>not</emphasis> the right answer! What is
|
||||
going on?</para>
|
||||
|
||||
<para>A. When the compiler sees you call a function, it checks if it
|
||||
</question>
|
||||
<answer>
|
||||
<para>When the compiler sees you call a function, it checks if it
|
||||
has already seen a prototype for it. If it has not, it assumes the
|
||||
function returns an <type>int</type>, which is
|
||||
definitely not what you want here.</para>
|
||||
|
||||
<para>Q. So how do I fix this?</para>
|
||||
|
||||
<para>A. The prototypes for the mathematical functions are in
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>So how do I fix this?</para>
|
||||
</question>
|
||||
<answer>
|
||||
<para>The prototypes for the mathematical functions are in
|
||||
<filename>math.h</filename>. If you include this file, the compiler
|
||||
will be able to find the prototype and it will stop doing strange
|
||||
things to your calculation!
|
||||
</para>
|
||||
<informalexample>
|
||||
<programlisting>#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
@ -589,94 +605,125 @@ things to your calculation!
|
|||
int main() {
|
||||
...</programlisting>
|
||||
</informalexample>
|
||||
</para>
|
||||
|
||||
<para>After recompiling it as you did before, run it:
|
||||
</para>
|
||||
<informalexample>
|
||||
<screen>$ <userinput>./a.out</userinput>
|
||||
<screen>&prompt.user; <userinput>./a.out</userinput>
|
||||
2.1 ^ 6 = 85.766121</screen>
|
||||
</informalexample>
|
||||
</para>
|
||||
|
||||
<para>If you are using any of the mathematical functions,
|
||||
<emphasis>always</emphasis> include <filename>math.h</filename> and
|
||||
remember to link in the math library.</para>
|
||||
|
||||
<para>Q. I compiled a file called <filename>foobar.c</filename> and I
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>I compiled a file called <filename>foobar.c</filename> and I
|
||||
cannot find an executable called <filename>foobar</filename>. Where's
|
||||
it gone?</para>
|
||||
|
||||
<para>A. Remember, <command>cc</command> will call the executable
|
||||
</question>
|
||||
<answer>
|
||||
<para>Remember, <command>cc</command> will call the executable
|
||||
<filename>a.out</filename> unless you tell it differently. Use the
|
||||
<option>-o <replaceable>filename</replaceable></option> option:
|
||||
<informalexample>
|
||||
<screen>$ <userinput>cc -o foobar foobar.c</userinput></screen>
|
||||
</informalexample>
|
||||
</para>
|
||||
|
||||
<para>Q. OK, I have an executable called <filename>foobar</filename>,
|
||||
<informalexample>
|
||||
<screen>&prompt.user; <userinput>cc -o foobar foobar.c</userinput></screen>
|
||||
</informalexample>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>OK, I have an executable called <filename>foobar</filename>,
|
||||
I can see it when I run <command>ls</command>, but when I type in
|
||||
<command>foobar</command> at the command prompt it tells me there is
|
||||
no such file. Why can it not find it?</para>
|
||||
|
||||
<para>A. Unlike <trademark>MS-DOS</trademark>, Unix does not look in the
|
||||
</question>
|
||||
<answer>
|
||||
<para>Unlike <trademark>MS-DOS</trademark>, Unix does not look in the
|
||||
current directory when it is trying to find out which executable you
|
||||
want it to run, unless you tell it to. Either type
|
||||
<command>./foobar</command>, which means <quote>run the file called
|
||||
<filename>foobar</filename> in the current directory</quote>, or
|
||||
change your <systemitem class=environvar>PATH</systemitem>
|
||||
environment variable so that it looks something like
|
||||
</para>
|
||||
<informalexample>
|
||||
<screen>bin:/usr/bin:/usr/local/bin:.</screen>
|
||||
</informalexample>
|
||||
<para>
|
||||
The dot at the end means <quote>look in the current directory if it is not in
|
||||
any of the others</quote>.</para>
|
||||
|
||||
<para>Q. I called my executable <filename>test</filename>, but
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>I called my executable <filename>test</filename>, but
|
||||
nothing happens when I run it. What is going on?</para>
|
||||
|
||||
<para>A. Most Unix systems have a program called
|
||||
</question>
|
||||
<answer>
|
||||
<para>Most Unix systems have a program called
|
||||
<command>test</command> in <filename>/usr/bin</filename> and the
|
||||
shell is picking that one up before it gets to checking the current
|
||||
directory. Either type:
|
||||
</para>
|
||||
<informalexample>
|
||||
<screen>$ <userinput>./test</userinput></screen>
|
||||
<screen>&prompt.user; <userinput>./test</userinput></screen>
|
||||
</informalexample>
|
||||
<para>
|
||||
or choose a better name for your program!</para>
|
||||
|
||||
<para>Q. I compiled my program and it seemed to run all right at
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>I compiled my program and it seemed to run all right at
|
||||
first, then there was an error and it said something about <errorname>core
|
||||
dumped</errorname>. What does that mean?</para>
|
||||
|
||||
<para>A. The name <firstterm>core dump</firstterm> dates back to the
|
||||
</question>
|
||||
<answer>
|
||||
<para>The name <firstterm>core dump</firstterm> dates back to the
|
||||
very early days of Unix, when the machines used core memory for
|
||||
storing data. Basically, if the program failed under certain
|
||||
conditions, the system would write the contents of core memory to
|
||||
disk in a file called <filename>core</filename>, which the programmer
|
||||
could then pore over to find out what went wrong.</para>
|
||||
|
||||
<para>Q. Fascinating stuff, but what I am supposed to do now?</para>
|
||||
|
||||
<para>A. Use <command>gdb</command> to analyse the core (see <xref
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>Fascinating stuff, but what I am supposed to do now?</para>
|
||||
</question>
|
||||
<answer>
|
||||
<para>Use <command>gdb</command> to analyse the core (see <xref
|
||||
linkend="debugging">).</para>
|
||||
|
||||
<para>Q. When my program dumped core, it said something about a
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>When my program dumped core, it said something about a
|
||||
<errorname>segmentation fault</errorname>. What's that?</para>
|
||||
|
||||
<para>A. This basically means that your program tried to perform some sort
|
||||
</question>
|
||||
<answer>
|
||||
<para>This basically means that your program tried to perform some sort
|
||||
of illegal operation on memory; Unix is designed to protect the
|
||||
operating system and other programs from rogue programs.</para>
|
||||
|
||||
<para>Common causes for this are:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
<listitem><para>Trying to write to a <symbol>NULL</symbol> pointer, eg
|
||||
</para>
|
||||
<programlisting>char *foo = NULL;
|
||||
strcpy(foo, "bang!");</programlisting>
|
||||
</para></listitem>
|
||||
</listitem>
|
||||
|
||||
<listitem><para>Using a pointer that hasn't been initialised, eg
|
||||
</para>
|
||||
<programlisting>char *foo;
|
||||
strcpy(foo, "bang!");</programlisting>
|
||||
<para>
|
||||
The pointer will have some random value that, with luck,
|
||||
will point into an area of memory that isn't available to
|
||||
your program and the kernel will kill your program before
|
||||
|
@ -686,51 +733,68 @@ data structures, causing the program to fail
|
|||
mysteriously.</para></listitem>
|
||||
|
||||
<listitem><para>Trying to access past the end of an array, eg
|
||||
</para>
|
||||
<programlisting>int bar[20];
|
||||
bar[27] = 6;</programlisting></para></listitem>
|
||||
bar[27] = 6;</programlisting></listitem>
|
||||
|
||||
<listitem><para> Trying to store something in read-only memory, eg
|
||||
</para>
|
||||
<programlisting>char *foo = "My string";
|
||||
strcpy(foo, "bang!");</programlisting>
|
||||
<para>
|
||||
Unix compilers often put string literals like
|
||||
<literal>"My string"</literal> into
|
||||
read-only areas of memory.</para></listitem>
|
||||
|
||||
<listitem><para>Doing naughty things with
|
||||
<function>malloc()</function> and <function>free()</function>, eg
|
||||
</para>
|
||||
<programlisting>char bar[80];
|
||||
free(bar);</programlisting>
|
||||
<para>
|
||||
or
|
||||
</para>
|
||||
<programlisting>char *foo = malloc(27);
|
||||
free(foo);
|
||||
free(foo);</programlisting>
|
||||
</para></listitem>
|
||||
</listitem>
|
||||
|
||||
</itemizedlist></para>
|
||||
</itemizedlist>
|
||||
|
||||
<para>Making one of these mistakes will not always lead to an
|
||||
error, but they are always bad practice. Some systems and
|
||||
compilers are more tolerant than others, which is why programs
|
||||
that ran well on one system can crash when you try them on an
|
||||
another.</para>
|
||||
|
||||
<para>Q. Sometimes when I get a core dump it says <errorname>bus
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>Sometimes when I get a core dump it says <errorname>bus
|
||||
error</errorname>. It says in my Unix book that this means a hardware
|
||||
problem, but the computer still seems to be working. Is this
|
||||
true?</para>
|
||||
|
||||
<para>A. No, fortunately not (unless of course you really do have a hardware
|
||||
</question>
|
||||
<answer>
|
||||
<para>No, fortunately not (unless of course you really do have a hardware
|
||||
problem…). This is usually another way of saying that you
|
||||
accessed memory in a way you shouldn't have.</para>
|
||||
|
||||
<para>Q. This dumping core business sounds as though it could be quite
|
||||
</answer>
|
||||
</qandaentry>
|
||||
<qandaentry>
|
||||
<question>
|
||||
<para>This dumping core business sounds as though it could be quite
|
||||
useful, if I can make it happen when I want to. Can I do this, or
|
||||
do I have to wait until there's an error?</para>
|
||||
|
||||
<para>A. Yes, just go to another console or xterm, do
|
||||
<screen>$ <userinput>ps</userinput></screen>
|
||||
</question>
|
||||
<answer>
|
||||
<para>Yes, just go to another console or xterm, do</para>
|
||||
<screen>&prompt.user; <userinput>ps</userinput></screen>
|
||||
<para>
|
||||
to find out the process ID of your program, and do
|
||||
<screen>$ <userinput>kill -ABRT <replaceable>pid</replaceable></userinput></screen>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>kill -ABRT <replaceable>pid</replaceable></userinput></screen>
|
||||
<para>
|
||||
where <parameter><replaceable>pid</replaceable></parameter> is the
|
||||
process ID you looked up.</para>
|
||||
|
||||
|
@ -738,6 +802,9 @@ process ID you looked up.</para>
|
|||
loop, for instance. If your program happens to trap
|
||||
<symbol>SIGABRT</symbol>, there are several other signals which have
|
||||
a similar effect.</para>
|
||||
</answer>
|
||||
</qandaentry>
|
||||
</qandaset>
|
||||
|
||||
</sect2>
|
||||
</sect1>
|
||||
|
@ -751,14 +818,18 @@ a similar effect.</para>
|
|||
|
||||
<para>When you're working on a simple program with only one or two source
|
||||
files, typing in
|
||||
<screen>$ <userinput>cc file1.c file2.c</userinput></screen>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>cc file1.c file2.c</userinput></screen>
|
||||
<para>
|
||||
is not too bad, but it quickly becomes very tedious when there are
|
||||
several files—and it can take a while to compile, too.</para>
|
||||
|
||||
<para>One way to get around this is to use object files and only recompile
|
||||
the source file if the source code has changed. So we could have
|
||||
something like:
|
||||
<screen>$ <userinput>cc file1.o file2.o</userinput> … <userinput>file37.c</userinput> &hellip</screen>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>cc file1.o file2.o</userinput> … <userinput>file37.c</userinput> &hellip</screen>
|
||||
<para>
|
||||
if we'd changed <filename>file37.c</filename>, but not any of the
|
||||
others, since the last time we compiled. This may speed up the
|
||||
compilation quite a bit, but doesn't solve the typing
|
||||
|
@ -805,8 +876,10 @@ are often used for documentation files like
|
|||
<title>Example of using <command>make</command></title>
|
||||
|
||||
<para>Here's a very simple make file:
|
||||
</para>
|
||||
<programlisting>foo: foo.c
|
||||
cc -o foo foo.c</programlisting>
|
||||
<para>
|
||||
It consists of two lines, a dependency line and a creation line.</para>
|
||||
|
||||
<para>The dependency line here consists of the name of the program
|
||||
|
@ -840,14 +913,17 @@ world</userinput> in the appropriate directory!</para>
|
|||
<para>Another useful property of makefiles is that the targets don't have
|
||||
to be programs. For instance, we could have a make file that looks
|
||||
like this:
|
||||
</para>
|
||||
<programlisting>foo: foo.c
|
||||
cc -o foo foo.c
|
||||
|
||||
install:
|
||||
cp foo /home/me</programlisting></para>
|
||||
cp foo /home/me</programlisting>
|
||||
|
||||
<para>We can tell make which target we want to make by typing:
|
||||
<screen>$ <userinput>make <replaceable>target</replaceable></userinput></screen>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>make <replaceable>target</replaceable></userinput></screen>
|
||||
<para>
|
||||
<command>make</command> will then only look at that target and ignore any
|
||||
others. For example, if we type <userinput>make foo</userinput> with the
|
||||
makefile above, make will ignore the <action>install</action> target.</para>
|
||||
|
@ -886,11 +962,11 @@ having to edit it.</para>
|
|||
BSD-based systems like FreeBSD come with some very powerful ones as
|
||||
part of the system. One very good example of this is the FreeBSD
|
||||
ports system. Here's the essential part of a typical ports
|
||||
<filename>Makefile</filename>:
|
||||
<filename>Makefile</filename>:</para>
|
||||
<programlisting>MASTER_SITES= ftp://freefall.cdrom.com/pub/FreeBSD/LOCAL_PORTS/
|
||||
DISTFILES= scheme-microcode+dist-7.3-freebsd.tgz
|
||||
|
||||
.include <bsd.port.mk></programlisting></para>
|
||||
.include <bsd.port.mk></programlisting>
|
||||
|
||||
<para>Now, if we go to the directory for this port and type
|
||||
<userinput>make</userinput>, the following happens:</para>
|
||||
|
@ -965,7 +1041,9 @@ have given you a base from which you can do this.</para>
|
|||
<para>The version of make that comes with FreeBSD is the <application>Berkeley
|
||||
make</application>; there is a tutorial for it in
|
||||
<filename>/usr/share/doc/psd/12.make</filename>. To view it, do
|
||||
<screen>$ <userinput>zmore paper.ascii.gz</userinput></screen>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>zmore paper.ascii.gz</userinput></screen>
|
||||
<para>
|
||||
in that directory.</para>
|
||||
|
||||
<para>Many applications in the ports use <application>GNU
|
||||
|
@ -979,7 +1057,9 @@ in its own right.</para>
|
|||
you will have to edit the <filename>dir</filename> file in the
|
||||
<filename>/usr/local/info</filename> directory to add an entry for
|
||||
it. This involves adding a line like
|
||||
</para>
|
||||
<programlisting> * Make: (make). The GNU Make utility.</programlisting>
|
||||
<para>
|
||||
to the file. Once you have done this, you can type
|
||||
<userinput>info</userinput> and then select
|
||||
<guimenuitem>make</guimenuitem> from the menu (or in
|
||||
|
@ -998,10 +1078,13 @@ i</userinput>).</para>
|
|||
<para>The debugger that comes with FreeBSD is called
|
||||
<command>gdb</command> (<application>GNU
|
||||
debugger</application>). You start it up by typing
|
||||
<screen>$ <userinput>gdb <replaceable>progname</replaceable></userinput></screen>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>gdb <replaceable>progname</replaceable></userinput></screen>
|
||||
<para>
|
||||
although most people prefer to run it inside
|
||||
<application>Emacs</application>. You can do this by:
|
||||
<screen><userinput>M-x gdb RET <replaceable>progname</replaceable> RET</userinput></screen></para>
|
||||
</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
|
||||
|
@ -1035,7 +1118,8 @@ debugging the kernel.</para>
|
|||
<command>gdb</command>. It will work without, but you'll only see the
|
||||
name of the function you're in, instead of the source code. If you
|
||||
see a line like:
|
||||
<screen>… (no debugging symbols found) …</screen>when
|
||||
</para>
|
||||
<screen>… (no debugging symbols found) …</screen><para>when
|
||||
<command>gdb</command> starts up, you'll know that the program wasn't
|
||||
compiled with the <option>-g</option> option.</para>
|
||||
|
||||
|
@ -1058,6 +1142,7 @@ pressing <command>f</command>. You can also use <command>up</command> and
|
|||
<para>Here's a simple example of how to spot a mistake in a program
|
||||
with <command>gdb</command>. This is our program (with a deliberate
|
||||
mistake):
|
||||
</para>
|
||||
<programlisting>#include <stdio.h>
|
||||
|
||||
int bazz(int anint);
|
||||
|
@ -1074,20 +1159,20 @@ int bazz(int anint) {
|
|||
printf("You gave me %d\n", anint);
|
||||
return anint;
|
||||
}</programlisting>
|
||||
</para>
|
||||
|
||||
<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>When we compile and run the program we get
|
||||
<screen>$ <userinput>cc -g -o temp temp.c</userinput>
|
||||
$ <userinput>./temp</userinput>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>cc -g -o temp temp.c</userinput>
|
||||
&prompt.user; <userinput>./temp</userinput>
|
||||
This is my program
|
||||
anint = 4231</screen></para>
|
||||
anint = 4231</screen>
|
||||
|
||||
<para>That wasn't what we expected! Time to see what's going
|
||||
on!<screen>$ <userinput>gdb temp</userinput>
|
||||
on!</para><screen>&prompt.user; <userinput>gdb temp</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.
|
||||
|
@ -1102,7 +1187,7 @@ Breakpoint 1, main () at temp.c:9 <lineannotation><command>gdb</command> stops
|
|||
This is my program <lineannotation>Program prints out</>
|
||||
(gdb) <userinput>s</> <lineannotation>step into <function>bazz()</></>
|
||||
bazz (anint=4231) at temp.c:17 <lineannotation><command>gdb</command> displays stack frame</>
|
||||
(gdb)</screen></para>
|
||||
(gdb)</screen>
|
||||
|
||||
|
||||
<para>Hang on a minute! How did <symbol>anint</symbol> get to be
|
||||
|
@ -1110,12 +1195,15 @@ bazz (anint=4231) at temp.c:17 <lineannotation><command>gdb</command> displays
|
|||
in <function>main()</function>? Let's move up to
|
||||
<function>main()</function> and have a look.</para>
|
||||
|
||||
<para><screen>(gdb) <userinput>up</> <lineannotation>Move up call stack</>
|
||||
<screen>(gdb) <userinput>up</> <lineannotation>Move up call stack</>
|
||||
#1 0x1625 in main () at temp.c:11 <lineannotation><command>gdb</command> displays stack frame</>
|
||||
(gdb) <userinput>p i</> <lineannotation>Show us the value of <symbol>i</></>
|
||||
$1 = 4231 <lineannotation><command>gdb</command> displays <literal>4231</></></screen>
|
||||
$1 = 4231 <lineannotation><command>gdb</command> displays <literal>4231</></>
|
||||
</screen>
|
||||
<para>
|
||||
Oh dear! Looking at the code, we forgot to initialise
|
||||
<symbol>i</symbol>. We meant to put
|
||||
</para>
|
||||
<programlisting><lineannotation>…</>
|
||||
main() {
|
||||
int i;
|
||||
|
@ -1123,6 +1211,7 @@ main() {
|
|||
i = 5;
|
||||
printf("This is my program\n");
|
||||
<lineannotation>&hellip</></programlisting>
|
||||
<para>
|
||||
but we left the <literal>i=5;</literal> line out. As we didn't
|
||||
initialise <symbol>i</symbol>, it had whatever number happened to be
|
||||
in that area of memory when the program ran, which in this case
|
||||
|
@ -1154,12 +1243,15 @@ file belongs to.</para>
|
|||
<para>To examine a core file, start up <command>gdb</command> in the
|
||||
usual way. Instead of typing <command>break</command> or
|
||||
<command>run</command>, type
|
||||
</para>
|
||||
<screen>(gdb) <userinput>core <replaceable>progname</replaceable>.core</userinput></screen>
|
||||
<para>
|
||||
If you're not in the same directory as the core file, you'll have to
|
||||
do <userinput>dir /path/to/core/file</userinput> first.</para>
|
||||
|
||||
<para>You should see something like this:
|
||||
<screen>$ <userinput>gdb a.out</userinput>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>gdb a.out</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.
|
||||
|
@ -1169,7 +1261,7 @@ Core was generated by `a.out'.
|
|||
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>
|
||||
(gdb)</screen>
|
||||
|
||||
<para>In this case, the program was called
|
||||
<filename>a.out</filename>, so the core file is called
|
||||
|
@ -1182,11 +1274,12 @@ called, as the problem could have occurred a long way up the call
|
|||
stack in a complex program. The <command>bt</command> command causes
|
||||
<command>gdb</command> to print out a back-trace of the call
|
||||
stack:
|
||||
</para>
|
||||
<screen>(gdb) <userinput>bt</userinput>
|
||||
#0 0x164a in bazz (anint=0x5) at temp.c:17
|
||||
#1 0xefbfd888 in end ()
|
||||
#2 0x162c in main () at temp.c:11
|
||||
(gdb)</screen>The <function>end()</function> function is called when
|
||||
(gdb)</screen><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>
|
||||
|
||||
|
@ -1204,13 +1297,15 @@ the parent.</para>
|
|||
|
||||
<para>What you do is start up another <command>gdb</command>, use
|
||||
<command>ps</command> to find the process ID for the child, and
|
||||
do<screen>(gdb) <userinput>attach <replaceable>pid</replaceable></userinput></screen>
|
||||
do</para><screen>(gdb) <userinput>attach <replaceable>pid</replaceable></userinput></screen>
|
||||
<para>
|
||||
in <command>gdb</command>, and then debug as usual.</para>
|
||||
|
||||
<para><quote>That's all very well,</quote> you're probably thinking,
|
||||
<quote>but by the time I've done that, the child process will be over
|
||||
the hill and far away</quote>. Fear not, gentle reader, here's how to
|
||||
do it (courtesy of the <command>gdb</command> info pages):
|
||||
</para>
|
||||
<screen><lineannotation>&hellip</lineannotation>
|
||||
if ((pid = fork()) < 0) /* _Always_ check this */
|
||||
error();
|
||||
|
@ -1222,6 +1317,7 @@ else if (pid == 0) { /* child */
|
|||
<lineannotation>&hellip</lineannotation>
|
||||
} else { /* parent */
|
||||
<lineannotation>&hellip</lineannotation></screen>
|
||||
<para>
|
||||
Now all you have to do is attach to the child, set
|
||||
<symbol>PauseMode</symbol> to <literal>0</literal>, and
|
||||
wait for the <function>sleep()</function> call to return!</para>
|
||||
|
@ -1259,6 +1355,7 @@ only to log out.</para>
|
|||
|
||||
<para>It's impossible even to summarise everything Emacs can do here, but
|
||||
here are some of the features of interest to developers:
|
||||
</para>
|
||||
<itemizedlist>
|
||||
|
||||
<listitem><para>Very powerful editor, allowing search-and-replace on
|
||||
|
@ -1289,7 +1386,7 @@ program.</para></listitem>
|
|||
<listitem><para>You can read Usenet news and mail while your program
|
||||
is compiling.</para></listitem>
|
||||
|
||||
</itemizedlist>And doubtless many more that I've overlooked.</para>
|
||||
</itemizedlist><para>And doubtless many more that I've overlooked.</para>
|
||||
|
||||
<para>Emacs can be installed on FreeBSD using <ulink
|
||||
URL="../../ports/editors.html">the Emacs
|
||||
|
@ -1386,7 +1483,6 @@ it's already running; it will read the commands from the file and
|
|||
<para>Unfortunately, there's far too much here to explain it in detail;
|
||||
however there are one or two points worth mentioning.</para>
|
||||
|
||||
<para>
|
||||
<itemizedlist>
|
||||
|
||||
<listitem><para>Everything beginning with a <literal>;</> is a
|
||||
|
@ -1423,7 +1519,9 @@ line.</para></listitem>
|
|||
<listitem><para> We enable Emacs's ability to act as a server, so
|
||||
that if you're doing something outside Emacs and you want to edit a
|
||||
file, you can just type in
|
||||
<screen>$ <userinput>emacsclient <replaceable>filename</replaceable></userinput></screen>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>emacsclient <replaceable>filename</replaceable></userinput></screen>
|
||||
<para>
|
||||
and then you can edit the file in your Emacs!<footnote><para>Many
|
||||
Emacs users set their <systemitem
|
||||
class=environvar>EDITOR</systemitem> environment to
|
||||
|
@ -1431,11 +1529,10 @@ class=environvar>EDITOR</systemitem> environment to
|
|||
to edit a file.</para></footnote></para></listitem>
|
||||
|
||||
</itemizedlist>
|
||||
</para>
|
||||
|
||||
<example>
|
||||
<title>A sample <filename>.emacs</filename> file</title>
|
||||
<screen>;; -*-Emacs-Lisp-*-
|
||||
<programlisting>;; -*-Emacs-Lisp-*-
|
||||
|
||||
;; This file is designed to be re-evaled; use the variable first-time
|
||||
;; to avoid any problems with this.
|
||||
|
@ -1509,9 +1606,9 @@ to edit a file.</para></footnote></para></listitem>
|
|||
(autoload 'ediff-buffers "ediff" "Intelligent Emacs interface to diff" t)
|
||||
(autoload 'ediff-files "ediff" "Intelligent Emacs interface to diff" t)
|
||||
(autoload 'ediff-files-remote "ediff"
|
||||
"Intelligent Emacs interface to diff") </screen>
|
||||
"Intelligent Emacs interface to diff")
|
||||
|
||||
<screen>(if first-time
|
||||
(if first-time
|
||||
(setq auto-mode-alist
|
||||
(append '(("\\.cpp$" . c++-mode)
|
||||
("\\.hpp$" . c++-mode)
|
||||
|
@ -1613,9 +1710,9 @@ in font-lock-auto-mode-list"
|
|||
(defun previous-error (n)
|
||||
"Visit previous compilation error message and corresponding source code."
|
||||
(interactive "p")
|
||||
(next-error (- n)))</screen>
|
||||
(next-error (- n)))
|
||||
|
||||
<screen>;; Misc...
|
||||
;; Misc...
|
||||
(transient-mark-mode 1)
|
||||
(setq mark-even-if-inactive t)
|
||||
(setq visible-bell nil)
|
||||
|
@ -1716,7 +1813,7 @@ in font-lock-auto-mode-list"
|
|||
|
||||
;; All done
|
||||
(message "All done, %s%s" (user-login-name) ".")
|
||||
</screen>
|
||||
</programlisting>
|
||||
</example>
|
||||
|
||||
</sect2>
|
||||
|
@ -1735,16 +1832,20 @@ comes with any files that tell Emacs about the language. These
|
|||
usually end in <filename>.el</filename>, short for <quote>Emacs
|
||||
Lisp</quote>. For example, if whizbang is a FreeBSD
|
||||
port, we can locate these files by doing
|
||||
<screen>$ <userinput>find /usr/ports/lang/whizbang -name "*.el" -print</userinput></screen>
|
||||
</para>
|
||||
<screen>&prompt.user; <userinput>find /usr/ports/lang/whizbang -name "*.el" -print</userinput></screen>
|
||||
<para>
|
||||
and install them by copying them into the Emacs site Lisp directory. On
|
||||
FreeBSD 2.1.0-RELEASE, this is
|
||||
<filename>/usr/local/share/emacs/site-lisp</filename>.</para>
|
||||
|
||||
<para>So for example, if the output from the find command was
|
||||
<screen>/usr/ports/lang/whizbang/work/misc/whizbang.el</screen>
|
||||
we would do
|
||||
<screen>$ <userinput>cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp</userinput></screen>
|
||||
</para>
|
||||
<screen>/usr/ports/lang/whizbang/work/misc/whizbang.el</screen>
|
||||
<para>
|
||||
we would do
|
||||
</para>
|
||||
<screen>&prompt.root; <userinput>cp /usr/ports/lang/whizbang/work/misc/whizbang.el /usr/local/share/emacs/site-lisp</userinput></screen>
|
||||
|
||||
<para>Next, we need to decide what extension whizbang source files
|
||||
have. Let's say for the sake of argument that they all end in
|
||||
|
@ -1755,11 +1856,13 @@ use the information in <filename>whizbang.el</filename>.</para>
|
|||
<para>Find the <symbol>auto-mode-alist entry</symbol> in
|
||||
<filename>.emacs</filename> and add a line for whizbang, such
|
||||
as:
|
||||
</para>
|
||||
<programlisting><lineannotation>…</>
|
||||
("\\.lsp$" . lisp-mode)
|
||||
("\\.wiz$" . whizbang-mode)
|
||||
("\\.scm$" . scheme-mode)
|
||||
<lineannotation>…</></programlisting>
|
||||
<para>
|
||||
This means that Emacs will automatically go into
|
||||
<function>whizbang-mode</function> when you edit a file ending in
|
||||
<filename>.wiz</filename>.</para>
|
||||
|
@ -1767,10 +1870,12 @@ This means that Emacs will automatically go into
|
|||
<para>Just below this, you'll find the
|
||||
<symbol>font-lock-auto-mode-list</symbol> entry. Add
|
||||
<function>whizbang-mode</function> to it like so:
|
||||
</para>
|
||||
<programlisting>;; Auto font lock mode
|
||||
(defvar font-lock-auto-mode-list
|
||||
(list 'c-mode 'c++-mode 'c++-c-mode 'emacs-lisp-mode 'whizbang-mode 'lisp-mode 'perl-mode 'scheme-mode)
|
||||
"List of modes to always start in font-lock-mode")</programlisting>
|
||||
<para>
|
||||
This means that Emacs will always enable
|
||||
<function>font-lock-mode</function> (ie syntax highlighting) when
|
||||
editing a <filename>.wiz</filename> file.</para>
|
||||
|
|
Loading…
Reference in a new issue