gdbint_13.html   [plain text]


<HTML>
<HEAD>
<!-- This HTML file has been created by texi2html 1.51
     from /mnt/apple/gdb/source/gdb.apple/source/gdb/gdb/doc/gdbint.texinfo on 23 November 1999 -->

<TITLE>GDB Internals - Coding</TITLE>
</HEAD>
<BODY>
Go to the <A HREF="gdbint_1.html">first</A>, <A HREF="gdbint_12.html">previous</A>, <A HREF="gdbint_14.html">next</A>, <A HREF="gdbint_16.html">last</A> section, <A HREF="gdbint_toc.html">table of contents</A>.
<P><HR><P>


<H1><A NAME="SEC90" HREF="gdbint_toc.html#TOC90">Coding</A></H1>

<P>
This chapter covers topics that are lower-level than the major
algorithms of GDB.

</P>


<H2><A NAME="SEC91" HREF="gdbint_toc.html#TOC91">Cleanups</A></H2>

<P>
Cleanups are a structured way to deal with things that need to be done
later.  When your code does something (like <CODE>malloc</CODE> some memory,
or open a file) that needs to be undone later (e.g. free the memory or
close the file), it can make a cleanup.  The cleanup will be done at
some future point: when the command is finished, when an error occurs,
or when your code decides it's time to do cleanups.

</P>
<P>
You can also discard cleanups, that is, throw them away without doing
what they say.  This is only done if you ask that it be done.

</P>
<P>
Syntax:

</P>
<DL COMPACT>

<DT><CODE>struct cleanup *<VAR>old_chain</VAR>;</CODE>
<DD>
Declare a variable which will hold a cleanup chain handle.

<DT><CODE><VAR>old_chain</VAR> = make_cleanup (<VAR>function</VAR>, <VAR>arg</VAR>);</CODE>
<DD>
Make a cleanup which will cause <VAR>function</VAR> to be called with
<VAR>arg</VAR> (a <CODE>char *</CODE>) later.  The result, <VAR>old_chain</VAR>, is a
handle that can be passed to <CODE>do_cleanups</CODE> or
<CODE>discard_cleanups</CODE> later.  Unless you are going to call
<CODE>do_cleanups</CODE> or <CODE>discard_cleanups</CODE> yourself, you can ignore
the result from <CODE>make_cleanup</CODE>.

<DT><CODE>do_cleanups (<VAR>old_chain</VAR>);</CODE>
<DD>
Perform all cleanups done since <CODE>make_cleanup</CODE> returned
<VAR>old_chain</VAR>.  E.g.:

<PRE>
make_cleanup (a, 0); 
old = make_cleanup (b, 0); 
do_cleanups (old);
</PRE>

will call <CODE>b()</CODE> but will not call <CODE>a()</CODE>.  The cleanup that
calls <CODE>a()</CODE> will remain in the cleanup chain, and will be done
later unless otherwise discarded.
<DT><CODE>discard_cleanups (<VAR>old_chain</VAR>);</CODE>
<DD>
Same as <CODE>do_cleanups</CODE> except that it just removes the cleanups from
the chain and does not call the specified functions.

</DL>

<P>
Some functions, e.g. <CODE>fputs_filtered()</CODE> or <CODE>error()</CODE>, specify
that they "should not be called when cleanups are not in place".  This
means that any actions you need to reverse in the case of an error or
interruption must be on the cleanup chain before you call these
functions, since they might never return to your code (they
<SAMP>`longjmp'</SAMP> instead).

</P>


<H2><A NAME="SEC92" HREF="gdbint_toc.html#TOC92">Wrapping Output Lines</A></H2>

<P>
Output that goes through <CODE>printf_filtered</CODE> or <CODE>fputs_filtered</CODE>
or <CODE>fputs_demangled</CODE> needs only to have calls to <CODE>wrap_here</CODE>
added in places that would be good breaking points.  The utility
routines will take care of actually wrapping if the line width is
exceeded.

</P>
<P>
The argument to <CODE>wrap_here</CODE> is an indentation string which is
printed <EM>only</EM> if the line breaks there.  This argument is saved
away and used later.  It must remain valid until the next call to
<CODE>wrap_here</CODE> or until a newline has been printed through the
<CODE>*_filtered</CODE> functions.  Don't pass in a local variable and then
return!

</P>
<P>
It is usually best to call <CODE>wrap_here()</CODE> after printing a comma or
space.  If you call it before printing a space, make sure that your
indentation properly accounts for the leading space that will print if
the line wraps there.

</P>
<P>
Any function or set of functions that produce filtered output must
finish by printing a newline, to flush the wrap buffer, before switching
to unfiltered ("<CODE>printf</CODE>") output.  Symbol reading routines that
print warnings are a good example.

</P>


<H2><A NAME="SEC93" HREF="gdbint_toc.html#TOC93">GDB Coding Standards</A></H2>

<P>
GDB follows the GNU coding standards, as described in
<TT>`etc/standards.texi'</TT>.  This file is also available for anonymous
FTP from GNU archive sites.  GDB takes a strict interpretation of the
standard; in general, when the GNU standard recommends a practice but
does not require it, GDB requires it.

</P>
<P>
GDB follows an additional set of coding standards specific to GDB,
as described in the following sections.

</P>
<P>
You can configure with <SAMP>`--enable-build-warnings'</SAMP> to get GCC to
check on a number of these rules.  GDB sources ought not to engender any
complaints, unless they are caused by bogus host systems.  (The exact
set of enabled warnings is currently <SAMP>`-Wall -Wpointer-arith
-Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations'</SAMP>.

</P>


<H3><A NAME="SEC94" HREF="gdbint_toc.html#TOC94">Formatting</A></H3>

<P>
The standard GNU recommendations for formatting must be followed
strictly.

</P>
<P>
Note that while in a definition, the function's name must be in column
zero; in a function declaration, the name must be on the same line as
the return type.

</P>
<P>
In addition, there must be a space between a function or macro name and
the opening parenthesis of its argument list (except for macro
definitions, as required by C).  There must not be a space after an open
paren/bracket or before a close paren/bracket.

</P>
<P>
While additional whitespace is generally helpful for reading, do not use
more than one blank line to separate blocks, and avoid adding whitespace
after the end of a program line (as of 1/99, some 600 lines had whitespace
after the semicolon).  Excess whitespace causes difficulties for diff and
patch.

</P>


<H3><A NAME="SEC95" HREF="gdbint_toc.html#TOC95">Comments</A></H3>

<P>
The standard GNU requirements on comments must be followed strictly.

</P>
<P>
Block comments must appear in the following form, with no `/*'- or
'*/'-only lines, and no leading `*':

</P>

<PRE>
/* Wait for control to return from inferior to debugger.  If inferior
   gets a signal, we may decide to start it up again instead of
   returning.  That is why there is a loop in this function.  When
   this function actually returns it means the inferior should be left
   stopped and GDB should read more commands.  */
</PRE>

<P>
(Note that this format is encouraged by Emacs; tabbing for a multi-line
comment works correctly, and M-Q fills the block consistently.)

</P>
<P>
Put a blank line between the block comments preceding function or
variable definitions, and the definition itself.

</P>
<P>
In general, put function-body comments on lines by themselves, rather
than trying to fit them into the 20 characters left at the end of a
line, since either the comment or the code will inevitably get longer
than will fit, and then somebody will have to move it anyhow.

</P>


<H3><A NAME="SEC96" HREF="gdbint_toc.html#TOC96">C Usage</A></H3>

<P>
Code must not depend on the sizes of C data types, the format of the
host's floating point numbers, the alignment of anything, or the order
of evaluation of expressions.

</P>
<P>
Use functions freely.  There are only a handful of compute-bound areas
in GDB that might be affected by the overhead of a function call, mainly
in symbol reading.  Most of GDB's performance is limited by the target
interface (whether serial line or system call).

</P>
<P>
However, use functions with moderation.  A thousand one-line functions
are just as hard to understand as a single thousand-line function.

</P>


<H3><A NAME="SEC97" HREF="gdbint_toc.html#TOC97">Function Prototypes</A></H3>

<P>
Prototypes must be used to <EM>declare</EM> functions but never to
<EM>define</EM> them.  Prototypes for GDB functions must include both the
argument type and name, with the name matching that used in the actual
function definition.

</P>
<P>
For the sake of compatibility with pre-ANSI compilers, define prototypes
with the <CODE>PARAMS</CODE> macro:

</P>

<PRE>
extern int memory_remove_breakpoint PARAMS ((CORE_ADDR addr,
                                             char *contents_cache));
</PRE>

<P>
Note the double parentheses around the parameter types.  This allows an
arbitrary number of parameters to be described, without freaking out the
C preprocessor.  When the function has no parameters, it should be
described like:

</P>

<PRE>
extern void noprocess PARAMS ((void));
</PRE>

<P>
The <CODE>PARAMS</CODE> macro expands to its argument in ANSI C, or to a
simple <CODE>()</CODE> in traditional C.

</P>
<P>
All external functions should have a <CODE>PARAMS</CODE> declaration in a
header file that callers include, except for <CODE>_initialize_*</CODE>
functions, which must be external so that <TT>`init.c'</TT> construction
works, but shouldn't be visible to random source files.

</P>
<P>
All static functions must be declared in a block near the top of the
source file.

</P>


<H3><A NAME="SEC98" HREF="gdbint_toc.html#TOC98">Clean Design</A></H3>

<P>
In addition to getting the syntax right, there's the little question of
semantics.  Some things are done in certain ways in GDB because long
experience has shown that the more obvious ways caused various kinds of
trouble.

</P>
<P>
You can't assume the byte order of anything that comes from a target
(including <VAR>value</VAR>s, object files, and instructions).  Such things
must be byte-swapped using <CODE>SWAP_TARGET_AND_HOST</CODE> in GDB, or one of
the swap routines defined in <TT>`bfd.h'</TT>, such as <CODE>bfd_get_32</CODE>.

</P>
<P>
You can't assume that you know what interface is being used to talk to
the target system.  All references to the target must go through the
current <CODE>target_ops</CODE> vector.

</P>
<P>
You can't assume that the host and target machines are the same machine
(except in the "native" support modules).  In particular, you can't
assume that the target machine's header files will be available on the
host machine.  Target code must bring along its own header files --
written from scratch or explicitly donated by their owner, to avoid
copyright problems.

</P>
<P>
Insertion of new <CODE>#ifdef</CODE>'s will be frowned upon.  It's much better
to write the code portably than to conditionalize it for various
systems.

</P>
<P>
New <CODE>#ifdef</CODE>'s which test for specific compilers or manufacturers
or operating systems are unacceptable.  All <CODE>#ifdef</CODE>'s should test
for features.  The information about which configurations contain which
features should be segregated into the configuration files.  Experience
has proven far too often that a feature unique to one particular system
often creeps into other systems; and that a conditional based on some
predefined macro for your current system will become worthless over
time, as new versions of your system come out that behave differently
with regard to this feature.

</P>
<P>
Adding code that handles specific architectures, operating systems,
target interfaces, or hosts, is not acceptable in generic code.  If a
hook is needed at that point, invent a generic hook and define it for
your configuration, with something like:

</P>

<PRE>
#ifdef	WRANGLE_SIGNALS
   WRANGLE_SIGNALS (signo);
#endif
</PRE>

<P>
In your host, target, or native configuration file, as appropriate,
define <CODE>WRANGLE_SIGNALS</CODE> to do the machine-dependent thing.  Take a
bit of care in defining the hook, so that it can be used by other ports
in the future, if they need a hook in the same place.

</P>
<P>
If the hook is not defined, the code should do whatever "most" machines
want.  Using <CODE>#ifdef</CODE>, as above, is the preferred way to do this,
but sometimes that gets convoluted, in which case use

</P>

<PRE>
#ifndef SPECIAL_FOO_HANDLING
#define SPECIAL_FOO_HANDLING(pc, sp) (0)
#endif
</PRE>

<P>
where the macro is used or in an appropriate header file.

</P>
<P>
Whether to include a <STRONG>small</STRONG> hook, a hook around the exact pieces of
code which are system-dependent, or whether to replace a whole function
with a hook depends on the case.  A good example of this dilemma can be
found in <CODE>get_saved_register</CODE>.  All machines that GDB 2.8 ran on
just needed the <CODE>FRAME_FIND_SAVED_REGS</CODE> hook to find the saved
registers.  Then the SPARC and Pyramid came along, and
<CODE>HAVE_REGISTER_WINDOWS</CODE> and <CODE>REGISTER_IN_WINDOW_P</CODE> were
introduced.  Then the 29k and 88k required the <CODE>GET_SAVED_REGISTER</CODE>
hook.  The first three are examples of small hooks; the latter replaces
a whole function.  In this specific case, it is useful to have both
kinds; it would be a bad idea to replace all the uses of the small hooks
with <CODE>GET_SAVED_REGISTER</CODE>, since that would result in much
duplicated code.  Other times, duplicating a few lines of code here or
there is much cleaner than introducing a large number of small hooks.

</P>
<P>
Another way to generalize GDB along a particular interface is with an
attribute struct.  For example, GDB has been generalized to handle
multiple kinds of remote interfaces -- not by #ifdef's everywhere, but
by defining the "target_ops" structure and having a current target (as
well as a stack of targets below it, for memory references).  Whenever
something needs to be done that depends on which remote interface we are
using, a flag in the current target_ops structure is tested (e.g.
`target_has_stack'), or a function is called through a pointer in the
current target_ops structure.  In this way, when a new remote interface
is added, only one module needs to be touched -- the one that actually
implements the new remote interface.  Other examples of
attribute-structs are BFD access to multiple kinds of object file
formats, or GDB's access to multiple source languages.

</P>
<P>
Please avoid duplicating code.  For example, in GDB 3.x all the code
interfacing between <CODE>ptrace</CODE> and the rest of GDB was duplicated in
<TT>`*-dep.c'</TT>, and so changing something was very painful.  In GDB 4.x,
these have all been consolidated into <TT>`infptrace.c'</TT>.
<TT>`infptrace.c'</TT> can deal with variations between systems the same way
any system-independent file would (hooks, #if defined, etc.), and
machines which are radically different don't need to use infptrace.c at
all.

</P>
<P>
Don't put debugging printfs in the code.

</P>

<P><HR><P>
Go to the <A HREF="gdbint_1.html">first</A>, <A HREF="gdbint_12.html">previous</A>, <A HREF="gdbint_14.html">next</A>, <A HREF="gdbint_16.html">last</A> section, <A HREF="gdbint_toc.html">table of contents</A>.
</BODY>
</HTML>