    <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:content="http://purl.org/rss/1.0/modules/content/">
     <channel>
        <title>ACCU  :: Error handling and logging</title>
        <link>https://members.accu.org/index.php/articles/504</link>
        <description>Professionalism in Programming</description>
        <dc:language>en-us</dc:language> 
        <dc:creator>Administrator</dc:creator> 
        <admin:generatorAgent rdf:resource="http://www.xaraya.org" /> 
        <admin:errorReportsTo rdf:resource="mailto:webeditor@accu.org" />
       <sy:updatePeriod>hourly</sy:updatePeriod>
       <sy:updateFrequency>1</sy:updateFrequency>
       <docs>http://backend.userland.com/rss</docs>




<div class="xar-mod-head"><span class="xar-mod-title">Programming Topics + Overload Journal #35 - Jan 2000</span></div>

<table border="0" cellpadding="1" cellspacing="0">
    <tbody>
    <tr>
        <td valign="top">
            Browse in :
       </td>
       <td valign="top">

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c13/">Topics</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c65/">Programming</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/">All</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c76/">Journals</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c78/">Overload</a>

                     &gt;                         <a href="https://members.accu.org/index.php/articles/c169/">35</a>
<br />

                                            <a href="https://members.accu.org/index.php/articles/c65-169/">Any of these categories</a>

                    -                        <a href="https://members.accu.org/index.php/articles/c65+169/">All of these categories</a>
<br />
</td>
   </tr>
   </tbody>
</table>




<div class="xar-error">
   <p>
 <strong>Note:</strong> when you create a new publication type,
the articles module will automatically use the templates
<em>user-display-[publicationtype].xt</em>
and <em>user-summary-[publicationtype].xt</em>.
If those templates do not exist when you try to preview or display a new article,
you'll get this warning :-)  Please place your own templates in themes/<em>yourtheme</em>/modules/articles . The templates will get the extension .xt there. </p>
</div>
<div class="xar-norm xar-standard-box-padding">
   <h1><strong>Title:</strong>&nbsp;Error handling and logging</h1>
<p><strong>Author:</strong>&nbsp;</p>
<p>
<strong>Date:</strong> 26 January 2000 16:50:55 +00:00 or Wed, 26 January 2000 16:50:55 +00:00</p>
<p><strong>Summary:</strong>&nbsp;</p>
<p><strong>Body:</strong>&nbsp;<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e18" id="d0e18"></a></h2>
</div>
<p>In my last article in Overload I presented code to facilitate
error logging. I'd like to stay with this theme and look at some of
the issues and concerns involved in logging.</p>
<p>When I speak of logging, I normally mean error logging. The
actual &quot;error logs&quot; may be errors, or they may be warnings and
information messages. An error log is one end of a spectrum, at the
other end is so called &quot;trace&quot; information which I will also
comment on. In addition I'll show how to catch some of NT's more
difficult exceptions.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e24" id="d0e24"></a>Exceptions and
libraries</h2>
</div>
<p>C++ provides us with the exceptions mechanism for raising, well,
exceptions. An exception is not necessarily and error, it is some
situation that occurs in a program which is so unusual as to be an
exception. The majority of these cases are errors, i.e. something
unusual has happened which is in error.</p>
<p>Exceptions provide us with a rich environment to encapsulate and
describe the condition that has arisen. All this information can be
placed in an object, and the object throw, like a message in a
bottle, which, through some angelic determinism<sup>[<a name=
"d0e31" href="#ftn.d0e31" id="d0e31">1</a>]</sup> will find a
suitable handler which can deal with it.</p>
<p>This mechanism is most powerful when considered in the light of
re-usable code libraries used in multiple projects. If we build a
library of classes to represent financial instruments, we may use
the library in big server boxes doing calculation for an investment
house, or in a workstation product used by floor traders, or even a
quick calculator for hand held machines. In each case we will want
to handle errors differently. Hence, we must abstract the exception
handling mechanism in such a way that the library user makes the
decision on what to do when a condition arises.</p>
<p>But wait! As developers, who will be called upon to fix the
problem, we need to know as much, specific information about how
the condition arose to enable us to find and fix the problem -
typically, the more information we have the quicker we can fix the
problem. This is at odds with our wish to abstract the
exception.</p>
<p>This is where the exception object comes into the picture. When
the condition arises the code which detects it should package all
the information it can into an object. The object is thrown and
when caught a policy decision can be made which determines what
happens next.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e41" id="d0e41"></a>Separate cause
and effect</h2>
</div>
<p>The above scenario describes the separation of cause (the
exception condition being encountered) and the effect of condition
(the functionality failing). This maps conveniently into our
developer-user view of the world. As the developer we are concerned
with the cause, because we want to fix it. Users, on the other
hand, are only concerned with the effect.</p>
<p>For example, if during a client-server TCP session the
connection is lost and the server query is aborted, the user is
only concerned with effect, their query has failed, they do not
care why it has failed<sup>[<a name="d0e48" href="#ftn.d0e48" id=
"d0e48">2</a>]</sup>. However, as a developer, I'm interested in
why was the connection lost, what error number was returned, what
was the socket state? And so on.</p>
<p>In this scenario, the throw statement is matched with the cause,
and the catch statement with the effect. Within the catch block the
effects of the condition are felt and action taken. This is where
we choose to deal with the condition and it is where the logging
should be placed.</p>
<p>The code I presented in my previous article could be used as a
bedrock layer upon which libraries can be built. Each library would
be able, through this bedrock to log errors. While this is
sometimes what we want, it is better to move the error logging to
higher levels where decisions on what action is taken, and what is
logged can be taken.</p>
<p>Another advantage of separating cause and effect is that we can
manage the quantity of information we present. A user does not want
to be bothered with a page of statements and a stack unwind, they
want a nice simple error message they can report to described what
has failed. To us developers a simple one liner like &quot;TCP socket
failed&quot; is next to useless, a several pages of messages and stack
unwind are just what we want! (A nice big red arrow pointing at a
bug would be helpful too, but I leave this as an exercise to the
reader!)</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e58" id="d0e58"></a>Tracing</h2>
</div>
<p>Tracing is a form of logging, but it does not deal exclusively
with errors. My preferred definition of tracing is: &quot;Tracing allows
a developer to see inside a program.&quot; Most developers are familiar
with the idea of adding debug code to a program so they can track
what is happening inside during development, but this code is
normally removed for release.</p>
<p>If we look beyond software development to the semiconductor
industry, or less abstractly, kitchen appliances and car,
manufactures increasingly leave &quot;debug code&quot; in place, and/or
provide interfaces through which diagnostics can be exposed. One of
my favourite examples are the inspection facilities built into
large civil-engineering projects so that bridges, tunnels and
building can be inspected once construction has finished.</p>
<p>This is where tracing comes in. We should actively seek to leave
inspection code in place in a program so that, when in live
operation we encounter a problem we have some diagnostic tools to
hand.</p>
<p>Before I go any further will address the point that many people
are already muttering: &quot;debug code comes out and allows run-time
speed to increase, if we leave in trace code run-times will be hit
and footprint increased&quot;. I won't try and deny this. Run-times will
be hit, but most of the time tracing is switched off, so we can
engineer our application so the only extra overhead is an
occasional if statement. When tracing is switched on performance is
hit more, but this only happens when we have an issue to
address.</p>
<p>While the run-time overhead argument may of been noticeable back
in the days of 6502 and Z80 processors with 64K of RAM, where every
cycle and every byte was valued, is the same true in the world of
600Mhz Pentium III's with 128Mb of RAM? Surely, when we specify the
machines for our applications we should include capacity for
tracing. Few engineering disciplines today would limit service and
maintenance opportunities. We accept that a car's engine is
accessible through the bonnet, even for those of us who never open
it, yet surely the car would be safer is it was welded shut? After
all, the garage mechanic can un-weld it when they need to open
it!</p>
<p>Trace statements can also be viewed as comments. Reading code
peppered with trace statements is even better than reading comment
code as we can see the comments executing, we can see the actual
path through the code, and any doubts we have about the actual
execution path are displayed.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e73" id="d0e73"></a>And some more
things</h2>
</div>
<p>I have not discussed several points that should be considered
when designing your exception handling and logging strategy. I hope
to cover at least some of them in a future article:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>Standard C++ exceptions: we now live in a world with a standard
C++ library of exception objects. While these may not be suitable
for every project, I think we should all plan to use them at the
outset of our design. Only abandon them if you find good reason.
Some of the common library function will throw exceptions of these
types, so you cannot ignore them altogether. Twelve months ago,
this may not of been my advice, but things move on.</p>
</li>
<li>
<p>Internationalisation: when designing error messages it is worth
considering what languages you will need to log errors in. This is
particularly important for user facing messages, developer specific
information and trace information is probably not worth
translating. In reality, I wager, most software has only one target
language<sup>[<a name="d0e85" href="#ftn.d0e85" id=
"d0e85">3</a>]</sup>. Microsoft tackles this problem with a
resource file residing in a separate DLL. While I praise their
attempt, I believe the Microsoft solution to event logging and
internationalisation of log messages is overly complex and lacks
any cross-platform merit.</p>
</li>
<li>
<p>Error codes: it is worth assigning error codes to specific
messages. Creating an include file which #defined the first error
as 1 and continues upwards is the wrong thing to do - this file
will inevitable be included in every other file, so whenever you
add a new error the whole project will need rebuilt<sup>[<a name=
"d0e92" href="#ftn.d0e92" id="d0e92">4</a>]</sup>. A better
solution is shown by Oracle, Sybase and other database vendors.
Here, areas of functionality are assigned short text codes, e.g.
SQL for query language functionality, NET for network functionality
and so on. Within each area a set of numeric codes is allocated, so
we have errors like SQL0001, SQL0002, etc.</p>
</li>
<li>
<p>Keep a central record of error messages your system can issue:
this is invaluable when documenting the system and running a help
desk to support the system. Even where the software does not
represent a commercial product it reduces the burden on anyone who
has to support the system by living with a pager and/or mobile
phone!</p>
</li>
<li>
<p>When devising an error code scheme, and an error message
document make sure they are easy to work with and expand. The last
thing you want is a developer saying: &quot;It's too much hassle to add
a new error message and number for this case, this existing code
and message is almost right so I'll just reuse that.&quot; For once, we
don't want to re-use code. Re-using this code will lead to
confusion for the technical author and help desk, let alone if the
text is translated to another language where it can't do double
service!</p>
</li>
</ul>
</div>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e102" id="d0e102"></a>Now for some
code...</h2>
</div>
<p>One of the problems with handling exceptions with C++ under
Windows NT is that the existence of two exception mechanisms. The
C++ mechanism which I'm sure all Overload readers know and love,
and the NT structured exception mechanism, this is a little like a
UNIX signal, when NT encounters an exception (e.g divide by zero,
memory corruption) it raises a structured exception.</p>
<p>An NT structured exception is an unsigned integer that
identifies the condition. It may be caught with a C++ catch-all
(<tt class="literal">catch(...)</tt>) but so is everything else.
Further, the stack management semantics are different, an NT
structured exception will not unwind the stack. This makes it
difficult to compile code with both mechanisms in use - indeed
Visual C++ will issue a warning message at the very least.</p>
<p>The solution, as shown here, is to install an exception
translator. This is done by registering a callback function using
the <tt class="function">_set_se_translator</tt> function:</p>
<pre class="programlisting">
_set_se_translator( Translator )
</pre>
<p>Once installed, NT will call the translator whenever it hits a
structured exception. (Shown in the listing <tt class=
"filename">NtSeTranslator.h</tt> &amp; <tt class=
"filename">.cpp</tt>.) This provides us with an opportunity to
create an object to represent the exception and throw this. A
problem occurs as NT calls the function for each stack frame as it
clears the stack, hence the translator will be called multiple
times so we cannot embed information within the exception object as
a new one is created and thrown at each stack level.</p>
<p>We can however, catch a translated exception using regular C++
catch semantics and obtain access the error code. We can also stop
the stack unwind when the catch occurs.</p>
<p>The code is in two parts. Firstly the actual translator
function, which is a large ugly switch statement. Secondly, the
translator class - <tt class="classname">SeTranslator</tt>.
<tt class="classname">SeTranslator</tt> implements an allocation is
initialisation metaphore to install the translator when an object
of SeTranslator is installed. Normally, I declare one of these just
inside the first try block of my code.</p>
<pre class="programlisting">
try {
  // install a translator
  Accu::SeTranslator translator;
  int *ptr = NULL;
  std::cout   &lt;&lt; &quot;Goodbye crewl world...&quot; 
      &lt;&lt; *ptr &lt;&lt; std::endl;
  return 0;
}
catch(Accu::StructuredException&amp; exp) {
  std::cerr   &lt;&lt; &quot;Something happened: &quot; 
      &lt;&lt; exp.what() &lt;&lt; std::endl;
  return 1;
}
</pre>
<p>I suspect that UNIX signals could be wrapped in such a way to
similarly throw an exception when received. This raises an
interesting cross platform handling technique.</p>
<p>I also include an exception class, StructuredException (in
listing StructuredException.h and .cpp), derived from
std::exception which is thrown when an NT structured exception is
throw.</p>
<p>Finally, over the time I have been using these classes, the most
useful facility is one that is not immediately obvious. Within the
debugger, place a break point inside the translator function. In
the event of a structured exception (e.g. de-referencing a null
pointer) the translator is called and the breakpoint encountered
resulting in a debugger trap at the point after the error occurred
with a full stack trace available and watch windows.</p>
</div>
<div class="sect1" lang="en">
<div class="titlepage">
<h2><a name="d0e145" id=
"d0e145"></a>Conclusion</h2>
</div>
<p>I hope I have convinced you that when thinking of exceptions we
need to think in terms of cause and effect, the cause maps to the
developer's view of the exception and the effect maps to the user's
view of what happened.</p>
<p>Under Windows NT the effect can sometimes be all to obvious and
the cause unknown, however, by bringing the NT exception handling
mechanism into the C++ world we can, once again, deal with cause
and effect.</p>
</div>
<div class="footnotes"><br>
<hr class="c2" width="100">
<div class="footnote">
<p><sup>[<a name="ftn.d0e31" href="#d0e31" id=
"ftn.d0e31">1</a>]</sup> This expression comes from a lecturer of
mine who used it to describe the way a non-deterministic automaton
reaches a stop state. I use it here to describe the way a catch
will be reached without the thrower being aware of where the catch
is in the program.</p>
</div>
<div class="footnote">
<p><sup>[<a name="ftn.d0e48" href="#d0e48" id=
"ftn.d0e48">2</a>]</sup> If the user can do something to rectify
the problem the situation is slightly different but the program
design must be such that allows a user to &quot;abort or retry&quot;.</p>
</div>
<div class="footnote">
<p><sup>[<a name="ftn.d0e85" href="#d0e85" id=
"ftn.d0e85">3</a>]</sup> I state this not as an objective of
software but as a reality.</p>
</div>
<div class="footnote">
<p><sup>[<a name="ftn.d0e92" href="#d0e92" id=
"ftn.d0e92">4</a>]</sup> This is the exact example John Lakos gives
(Large Scale C++ Software Design, 1996) of a practice that will
lead to problems on large projects.</p>
</div>
</div></p>
<p><strong>Notes:</strong>&nbsp;</p>
<p><em>More fields may be available via dynamicdata ..</em></p>
</div>
</channel>
</rss>
