T.R | Title | User | Personal Name | Date | Lines |
---|
3871.1 | suggestion | FLOYD::YODER | It's 999,943 to 1 but it just might work | Mon May 12 1997 12:57 | 15 |
| 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.2 | Few suggestions | KMOOSE::CMCCUTCHEON | Charlie McCutcheon | Mon May 12 1997 14:36 | 22 |
| > 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.3 | will do | CUJO::SAMPSON | | Mon May 12 1997 19:51 | 1 |
| Okay, thank you both for the suggestions!
|
3871.4 | big hammer | CUJO::SAMPSON | | Tue May 13 1997 22:36 | 7 |
| 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.5 | wish list | CUJO::SAMPSON | | Tue May 13 1997 22:41 | 9 |
| 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.6 | compile-time detection is impossible in general | BEGIN::YODER | It's 999,943 to 1 but it just might work | Wed May 14 1997 10:44 | 15 |
| 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.7 | how about more informative run-time errors? | CUJO::SAMPSON | | Wed May 14 1997 10:53 | 3 |
| 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.8 | probably not | FLOYD::YODER | It's 999,943 to 1 but it just might work | Wed May 14 1997 13:03 | 17 |
| >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.9 | how do I fix a circular dependency? | CUJO::SAMPSON | | Thu May 15 1997 01:07 | 28 |
| 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.10 | proceeding from here | BEGIN::YODER | It's 999,943 to 1 but it just might work | Thu May 15 1997 10:52 | 19 |
| 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.11 | other methods | FLOYD::YODER | It's 999,943 to 1 but it just might work | Thu May 15 1997 14:34 | 12 |
| 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.12 | will try to put your information to good use | CUJO::SAMPSON | | Fri May 16 1997 00:01 | 4 |
| 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.13 | oh, its needed all right | FLOYD::YODER | It's 999,943 to 1 but it just might work | Fri May 16 1997 15:02 | 18 |
| 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.14 | will take time; looks like we have time | CUJO::SAMPSON | | Fri May 16 1997 23:21 | 7 |
| >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.
|