The evil exiting parrot api

Bart Wiegmans bartwiegmans at gmail.com
Mon Jul 2 20:01:36 UTC 2012


Hi Andrew,

I promised to write up on the evil exiting parrot API, at least in
relation to apache.
To get some context, let me first explain how the interpreter is
instantiated and run.
First, I make an interpreter in mod_parrot_interpreter. Secondly, I
load apache.pbc using Parrot_api_load_bytecode_file and
Parrot_api_ready_bytecode. It should be noted that apache.winxed has a
meaningful 'main' sub which sets up the standard handles. It uses
dlfunc and NCI extensively.
Secondly, a 'loader' bytecode is loaded, readied and the main
subroutine invoked. This subroutine subsequently invokes code from
apache.winxed. Exceptions are 'handled' by mod_parrot_report_error,
which prints them out to the standard error log.

Basically, all you have to do to see this failure is the following:

- Update mod_parrot.git
- open loader/echo.winxed in your favourite editor
- add to the last line in the main function: throw new Exception. or
die(), or whatever. It is of no significance, as long as it both
compiles and crashes
- save your file and exit
- type in the main directory: make debug. This builds the entire
project and starts gdb with apache configured to load the module and
everything related. It listens on port 8000.
- add the breakpoint: break Parrot_x_jump_out
- start another terminal, and request a page that mod_parrot will
handle. As this is the echo loader that is loaded, any URI ending with
.winxed. Thus: curl http://localhost:8000/foobar.winxe
- this will not ever return with a response, Instead, switch to the
terminal running gdb. You should now be at your breakpoint, where you
can inspect all variables. interp is defined, as well as the
backtrace.

At this point you can experiment with putting the thrown exception in
any other place.
- on the first line of the subroutine, no crash
- in apache.setup (the subroutine defined in the other bytecode file), no crash
- after this subroutine, and after a call to say and status (which
both use NCI), no crash
-  however, after a call to getsdin().headers(), which uses the parrot
api to create a hash containing all inbound headers, a crash
(finally!)
- And yes, this depends on the jump buffer
- So in short, it seems that the api_jmp_buf is zeroed when using the
api to instantiate an object.

Wow, that seems really insightful, although I have no idea what to do with it.
I will cc this to the mailinglist, too, maybe anybody else has an idea.

tl;dr;
interp->api_jmp_buf is zeroed upon api use within an NCI function,
which is wrong in my perspective.

Kind regards,
Bart Wiegmans


More information about the parrot-dev mailing list