How do I get an unhandled exception to be reported in SML/NJ?

482 views Asked by At

I have the following SML program in a file named testexc.sml:

structure TestExc : sig
               val main : (string * string list -> int)
               end =
  struct

  exception OhNoes;

     fun main(prog_name, args) = (
       raise OhNoes
     )

end

I build it with smlnj-110.74 like this:

ml-build sources.cm TestExc.main testimg

Where sources.cm contains:

Group is
  csx.sml

I invoke the program like so (on Mac OS 10.8):

sml @SMLload testimg.x86-darwin

I expect to see something when I invoke the program, but the only thing I get is a return code of 1:

$ sml @SMLload testimg.x86-darwin
$ echo $?
1

What gives? Why would SML fail silently on this unhandled exception? Is this behavior normal? Is there some generic handler I can put on main that will print the error that occurred? I realize I can match exception OhNoes, but what about larger programs with exceptions I might not know about?

1

There are 1 answers

0
user3093557 On BEST ANSWER

The answer is to handle the exception, call it e, and print the data using a couple functions available in the system:

$ sml
Standard ML of New Jersey v110.74 [built: Tue Jan 31 16:23:10 2012]
- exnName;
val it = fn : exn -> string
- exnMessage;
val it = fn : exn -> string
-

Now, we have our modified program, were we have the generic handler tacked on to main():

structure TestExc : sig
               val main : (string * string list -> int)
               end =
  struct

  exception OhNoes;
  open List;

     fun exnToString(e) =
        List.foldr (op ^) "" ["[",
                              exnName e,
                              " ",
                              exnMessage e,
                              "]"]

     fun main(prog_name, args) = (
       raise OhNoes
     )
     handle e => (
       print("Grasshopper disassemble: " ^ exnToString(e));
       42)

end

I used lists for generating the message, so to make this program build, you'll need a reference to the basis library in sources.cm:

Group is
  $/basis.cm
  sources.cm

And here's what it looks like when we run it:

$ sml @SMLload testimg.x86-darwin
Grasshopper disassemble: [OhNoes OhNoes (more info unavailable: ExnInfoHook not initialized)]
$ echo $?
42

I don't know what ExnInfoHook is, but I see OhNoes, at least. It's too bad the SML compiler didn't add a basic handler for us, so as to print something when there was an unhandled exception in the compiled program. I suspect ml-build would be responsible for that task.