Monday, 14 January 2013

Tracking down a Program_Error

A StackOverflow question about a Storage_Error exception when trying to implement a FastCGI example in Ada prompted me to investigate.

The first thing is, of course, to build the FastCGI library. The latest released version is dated January 2003; nothing wrong with that!

It built with no problems (I configured with --prefix=$HOME/local).

Next, build the Ada code in question with debugging, retention of stack tracing, and with a non-position-independent executable; see here for a discussion.

gnatmake -f -g test \
  -bargs -E \
  -largs -Wl,-no_pie -L$HOME/local/lib -lfcgi

On running the program, we get

$ ./test
Execution terminated by unhandled exception
Exception name: PROGRAM_ERROR
Message: unhandled signal
Call stack traceback locations:
0x100009a81 0x7fff8f37b8e8 0x100035f24 0x100000b62 0x100000b0a

and decoding the stack trace gives

$ atos -o test 0x100009a81 0x7fff8f37b8e8 0x100035f24 0x100000b62 0x100000b0a
__gnat_error_handler (in test) + 65
0x7fff8f37b8e8
0x100035f24
_ada_test (in test) (test.adb:8)
main (in test) (b~test.adb:148)

which tells us that the failing line in test.adb was line 8

fcgi_stdio.FCGI_printf
  (Interfaces.C.Strings.New_String ("Content-Type: text/plain"
   & ASCII.LF & ASCII.LF));

but not what happened in the call to the library procedure.

Clearly the shared library libfcgi.dylib doesn't contain debug symbols (well, not ones that atos can see); try linking against the static library libfcgi.a:

gnatmake -f -g test \
  -bargs -E \
  -largs -Wl,-no_pie $HOME/local/lib/libfcgi.a

Now, running the program results in

./test
Execution terminated by unhandled exception
Exception name: PROGRAM_ERROR
Message: unhandled signal
Call stack traceback locations:
0x10000f701 0x7fff8f37b8e8 0x100004e84 0x100001772 0x10000171a

and decoding the stack trace gives

$ atos -o test 0x10000f701 0x7fff8f37b8e8 0x100004e84 0x100001772 0x10000171a
__gnat_error_handler (in test) + 65
0x7fff8f37b8e8
FCGI_fprintf (in test) (fcgi_stdio.c:601)
_ada_test (in test) (test.adb:8)
main (in test) (b~test.adb:148)

so we've narrowed the problem to line 601 of fcgi_stdio.c,

int FCGI_fprintf(FCGI_FILE *fp, const char *format, ...)
{
    va_list ap;
    int n = 0;
    va_start(ap, format);             (line 601)

and it's a problem with variable argument lists (varargs).

A bit of googling leads to the GNAT online docs; Ada doesn't support varargs functions, and you need to provide a plain C wrapper and import that.

No comments:

Post a Comment