[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::ada

Title:DEC Ada
Notice:Ada is no longer a trademark of the US Government
Moderator:KMOOSE::CMCCUTCHEON
Created:Mon Jan 27 1986
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:3874
Total number of notes:16668

3871.0. "PROGRAM_ERROR EXCRAIPRI" by CUJO::SAMPSON () Sat May 10 1997 03:23

	Hello again Charlie,

	After successfully compiling and linking the customer program
mentioned in 3870.5, it dies at run time during elaboration (before
running the main program).  This occurs on OpenVMS, both VAX and Alpha.

	The customer claims that the program runs without problems on
a variety of other platforms (SGI, Sun, and PC).  He also says that the
program makes use of Ada tasking, and claims that he has had trouble
using this feature in the past.

	The source code is not available, so I'm trying to get it chopped
down into a manageably small test case for you.  I'm hoping that the
traceback by itself may be helpful.  So far the problem has eluded my
attempts to find it with the debugger.  Any advice on what to look for
would be appreciated.

	The source code at module SOME_ADA_UNIT_NAME, line #73,
has the general appearance of "procedure x is new y.z", and generates
a call, if that helps at all.

	The problem has been observed with the following combinations
of software:

(1) OpenVMS VAX   V7.1, DEC Ada T3.4    (traceback is shown below).
(2) OpenVMS Alpha V7.1, DEC Ada V3.3-23 (traceback available if needed).
(3) OpenVMS Alpha V6.2, DEC Ada V3.3-7  (customer's configuration).

$ run/nodebug TSTADA
%ADA-F-PROGRAM_ERROR, PROGRAM_ERROR
-ADA-I-EXCRAIPRI, Exception raised prior to PC = 0005104C
%TRACE-E-TRACEBACK, symbolic stack dump follows
module name     routine name                     line       rel PC    abs PC

ADARTL                                                     0013D24E  0013D24E
----- above condition handler called with exception 00318964:
%ADA-F-PROGRAM_ERROR, PROGRAM_ERROR
-ADA-I-EXCRAIPRI, Exception raised prior to PC = 0005104C
----- end of exception message
ADARTL                                                     0013BF61  0013BF61
SOME_ADA_UNIT_N SOME_ADA_UNIT_NAME$ELAB            73      0000019C  0005104C
TSTADA          (LIB$INITIALIZE)                           0000002F  000E1D32
ADARTL                                                     0013D01D  0013D01D
ADA$ELAB_TSTADA ADA$ELAB_TSTADA                            0000001B  0002FA1B
TSTADA          (LIB$INITIALIZE)                           0000002F  000E1D32
T.RTitleUserPersonal
Name
DateLines
3871.1suggestionFLOYD::YODERIt's 999,943 to 1 but it just might workMon May 12 1997 15:5715
There isn't much to go on here, but there's a simple thing to try.

It is most likely that DEC Ada is finding an error that the other compilers
don't.  I've seen this often: when changing to a better compiler, the new
compiler makes errors manifest that were uncaught by the older compiler, and it
looks like the new compiler has "caused" the problem.  (Incidentally, most of
the cases I saw were people changing to a Verdix compiler, not Digital's.)

In this case, one possibility is an elaboration order problem.  If the unit 'y'
is a library package, try adding 'pragma Elaborate(y);' to the library unit that
contains the declaration of the procedure 'x'.  More generally, you can look for
"obvious" cases of a routine being called before it is elaborated.  (Very
roughly speaking, a routine is elaborated where its body is declared.)

Otherwise, we may need to ask for a reproducer.  Good luck.
3871.2Few suggestionsKMOOSE::CMCCUTCHEONCharlie McCutcheonMon May 12 1997 17:3622
>	The source code is not available, so I'm trying to get it chopped
>down into a manageably small test case for you.  I'm hoping that the
>traceback by itself may be helpful.  So far the problem has eluded my

Generally a traceback from a user's program isn't very useful to us.
We didn't write the program, so we are fairly limited as to what we
can contribute.

The traceback you give tells me only that the program raised a program_error,
not any clues as to why.

Note that you can debug elaboration code.  Look for *$elab symbols:

	dbg> show symb foo$elab
	dbg> set break foo$elab

Or:
	dbg> set break /exception
	dbg> go
	dbg> ! Debug at the place the exception is raised...

Charlie
3871.3will doCUJO::SAMPSONMon May 12 1997 22:511
	Okay, thank you both for the suggestions!
3871.4big hammerCUJO::SAMPSONWed May 14 1997 01:367
	Today I finally resorted to the big hammer, which is to force a
recompile with /NOCHECK.  This allows the program to run.  Using PRAGMA
ELABORATE succeeded in shifting the PC of the PROGRAM_ERROR exception
from "SOME_ADA_UNIT_NAME$ELAB" to "y$ELAB".  I was unable to eliminate
this new problem with another PRAGMA ELABORATE, though.  I haven't had
any success so far with PRAGMA SUPPRESS (ELABORATION_CHECK), either.
I haven't tried using PRAGMA SUPPRESS_ALL yet.
3871.5wish listCUJO::SAMPSONWed May 14 1997 01:419
	BTW, just in case no one has asked for this before, it would be
very nice if the PROGRAM_ERROR exception message would specify the name
of the package that unexpectedly hasn't been elaborated yet at run time.

	Also, couldn't/shouldn't the compiler have the ability to warn
*at compile time* that these run-time errors are likely to occur?

	Thanks, just wondering,
	Bob Sampson
3871.6compile-time detection is impossible in generalBEGIN::YODERIt's 999,943 to 1 but it just might workWed May 14 1997 13:4415
    The compiler does detect circular dependencies, but detection of all
    elaboration order errors is impossible because it is equivalent to
    solving the halting problem.
    
    Beware that what you have found strongly suggests that there is a
    real *error* in the program, i.e., it's illegal Ada.  It's entirely
    possible, for example, that an uninitialized variable is being used,
    and the fact that the program seems to work may depend on what the
    accidental contents of this variable are.  (Of course, there is also
    some chance that the error is genuinely harmless.)
    
    Oh, the comment above about the compiler being unable to detect all
    errors applies at link time too: that's why the elaboration order
    check is, in general, done at run time.
    
3871.7how about more informative run-time errors?CUJO::SAMPSONWed May 14 1997 13:533
    Thanks for the explanation.  What about the idea of making the run-time
    error more explicit about which package(s) haven't been elaborated yet?
    Could that be added without too much effort?
3871.8probably notFLOYD::YODERIt's 999,943 to 1 but it just might workWed May 14 1997 16:0317
>What about the idea of making the run-time
>error more explicit about which package(s) haven't been elaborated yet?
>Could that be added without too much effort?

Probably no, but there's a simple method to find the error which has the
advantage that each iteration fixes a genuine bug.

If the exception happens in foo$elab, it's a sign that 'foo' is missing a needed
pragma Elaborate.  Most packages have simple initialization, so it hopefully
isn't too hard to add the ones it needs.  (In general, if the initialization for
'foo' contains a call to a procedure, or an instance of a generic, within a
package 'bar', you must put 'bar' in a pragma Elaborate attached to 'foo'.)

In a short time, you should either find that the problem goes away or find there
is a circular dependence.  (If you are dealing with hundreds or thousands of
modules, it's *possible* to run into a large circle, but I've never seen it
happen.  They're usually just a few units.)
3871.9how do I fix a circular dependency?CUJO::SAMPSONThu May 15 1997 04:0728
	Okay, I've done some of that (iteratively added PRAGMA ELABORATEs),
and ended up with a circular dependency involving three packages.  How would
I fix that (without having to learn the minutiae of Ada)?  I guess I'm still
unclear about what constitutes the bug I'm trying to stamp out.

	One annoying thing about this iterative approach is that, every
time I load a changed unit into the library, it makes up to a couple of
dozen units obsolete, so recompiles take several minutes each on my
reasonably-fast VAXstation 4000/90A, and about twice as long on a
rather-slow Alpha (DEC 3000-500).  Of course I could make use of one of
the customer's AlphaServer 4100's, but the ones running the latest
software are physically remote, and the network link has been neither
fast nor reliable lately.

	That's why I would like to stress that it would be ideal (from
a naive user's perspective) if the run-time PROGRAM_ERROR would tell me
exactly what is wrong with the program, and give me enough precise
information so that I would know exactly how to fix it.

	Today I applied a hammer somewhat smaller than /NOCHECK.  By adding
PRAGMA SUPPRESS_ALL at the end of two package bodies (which I have called
SOME_ADA_UNIT_NAME and Y in this notes string), the program is allowed to
run.  I have had no success at all so far with even smaller hammers
(adding PRAGMA SUPPRESS (ELABORATION_CHECK [ , ON => xyz ] ) where it
seemed appropriate.

	Thanks,
	Bob Sampson
3871.10proceeding from hereBEGIN::YODERIt's 999,943 to 1 but it just might workThu May 15 1997 13:5219
    I agree with you about the utility of what you're asking for.
    I don't want to encourage requests for new features because we haven't
    the resources to do development beyond a very minimal level.
    
    DEC Ada doesn't implement the finer-grained version of pragma Suppress,
    where it is applied to a particular object.  Remember that a compiler
    is not *ever* obligated to suppress a check, though failing to do so
    at the cost of runtime is IMO unfriendly.
    
    If you have a circular dependency, it means the user's initialization
    has a bug because there are 3 packages (or whatever), each of which
    requires that the other 2 be initialized first.  How to fix it requires
    a knowledge of what the packages are trying to achieve.  There are
    probably many ways to fix it, and I'm certainly ready to help.  For
    example, one method might be to remove the "common" initialization to
    a 4th unit, and then have the 3 bodies depend only on this other unit.
    (That's not necessarily the best way, I'm just trying to illustrate
    the sorts of options available.)
    
3871.11other methodsFLOYD::YODERIt's 999,943 to 1 but it just might workThu May 15 1997 17:3412
Here are some other ways to fix circular dependencies, taken from past
experience.  These cases were Pascal units or Modula-2 modules, but the
principles are identical.

Case 1. Two units had the property that their initialization each used the other
unit.  Examing one led to the observation that its initialization was solely for
the sake of a single routine that was nice but not necessary.  That routine was
eliminated, making the unit's initialization null.

Case 2. A strings package and an errors package each required that the other be
initialized first.  Since the strings package only used fatal errors, the errors
package was split into two, one with fatal errors and one with non-fatal errors.
3871.12will try to put your information to good useCUJO::SAMPSONFri May 16 1997 03:014
	Okay, thanks.  For now, the PRAGMA SUPPRESS_ALL at the end of the
two package bodies will allow the customer to investigate the run-time
behavior of the program.  The circular dependency can be revisited after
that, as needed.
3871.13oh, its needed all rightFLOYD::YODERIt's 999,943 to 1 but it just might workFri May 16 1997 18:0218
I may have been insufficiently alarmist in my previous notes.  :-)

The damage that this sort of bug *can* do is completely unlimited,
especially if the units in question use pointers.  The fact that it's
caught by DEC Ada doesn't mean it's overly picky, it means the other
compilers have buggy elaboration code.  It is just as wrong for a
compiler to miss raising Program_Error here as it would be to miss a
syntactic error.  (There's very good reasons for these checks being
required!)

It may be that the code that is generated accidentally causes no
harmful errors.  It's also possible that it is failing, or that it
fails the first time it's called, or almost anything else.  But it will
be necessary for the user to revisit this problem in order to make
legal Ada.

If you could post an outline of what is causing the problem, I'd be
happy to see if there's an easy fix.
3871.14will take time; looks like we have timeCUJO::SAMPSONSat May 17 1997 02:217
>If you could post an outline of what is causing the problem, I'd be
>happy to see if there's an easy fix.

	It will take some time (weeks?) for me to make that much progress.
Even if there is a subtle problem caused by incomplete elaboration,
the customer probably won't know or care for a while, so long as the
program behaves on OpenVMS the same way it does on SGI, etc.