petdance/scratch — Issue #380: Oplib paths are truncated in PBC files
Author: petdance
Created: 2011-11-01 04:25:50+00:00
State: open

The problem seems to be that IMCC uses the correct path to load the oplib object file when compiling, but drops all directory information when producing the packfile, so that loading the PBC file fails to find the library.

1. Unpack the attached test case tarball, and edit the PARROT-HOME macro in the makefile to point to a local Parrot working copy.

2. Run "make" to build and run the test. Here's what the output looks like on my machine (GNU/Linux, openSUSE 11.3):

rogers@rgr> make
/usr/src/parrot/ops2c --dynamic dynops/kea_cl.ops --quiet
cc -I/usr/src/parrot/include -I/usr/src/parrot/include/pmc \
-o dynops/kea_cl_ops.o -c dynops/kea_cl_ops.c
ld -o dynops/kea_cl_ops.so dynops/kea_cl_ops.o -shared
/usr/src/parrot/parrot -o test.pbc test.pir
/usr/src/parrot/parrot -o aux.pbc aux.pir
/usr/src/parrot/parrot test.pbc
Could not load oplib `kea_cl_ops'
current instr.: 'main' pc 0 (test.pir:4)
make: *** [test] Error 1
rogers@rgr>

3. Apply parrot-lib-debugging.patch to the Parrot working copy, do "make parrot", and rerun the test:

rogers@rgr> make clean
rm -f *.pbc *.dump *.dis dynops/kea_cl_ops.*
rogers@rgr> make
/usr/src/parrot/ops2c --dynamic dynops/kea_cl.ops --quiet
Got path '/usr/src/parrot/runtime/parrot/dynext/os.so' for os
cc -I/usr/src/parrot/include -I/usr/src/parrot/include/pmc \
-o dynops/kea_cl_ops.o -c dynops/kea_cl_ops.c
ld -o dynops/kea_cl_ops.so dynops/kea_cl_ops.o -shared
/usr/src/parrot/parrot -o test.pbc test.pir
Got path 'dynops/kea_cl_ops.so' for dynops/kea_cl_ops
/usr/src/parrot/parrot -o aux.pbc aux.pir
Got path 'dynops/kea_cl_ops.so' for dynops/kea_cl_ops
/usr/src/parrot/parrot test.pbc
Got path '' for kea_cl_ops
Could not load oplib `kea_cl_ops'
current instr.: 'main' pc 0 (test.pir:4)
make: *** [test] Error 1
rogers@rgr>

This shows that IMCC is looking for "dynops/kea_cl_ops" (as you would expect), but the PBC file is looking for "kea_cl_ops" at load time and failing. Indeed, if you do "strings aux.pbc", you will find the latter but not the former. (As an aside, pbc_dump and pbc_disassemble do not work on aux.pbc. Unless you copy dynops/kea_cl_ops.so to runtime/parrot/dynext/ in the Parrot working copy, where it will be found.)

4. Change the aux.pir source to use the absolute pathname. This does not help:

rogers@rgr> make
/usr/src/parrot/parrot -o aux.pbc aux.pir
Got path '/home/rogers/projects/kea2/bug/dynops/kea_cl_ops.so' for /home/rogers/projects/kea2/bug/dynops/kea_cl_ops
/usr/src/parrot/parrot test.pbc
Got path '' for kea_cl_ops
Could not load oplib `kea_cl_ops'
current instr.: 'main' pc 0 (test.pir:4)
make: *** [test] Error 1
rogers@rgr>

As before, just "kea_cl_ops" is stored in the PBC file.

FWIW, Parrot has never had this problem with dynamic PMC classes; the exact pathname used in the .loadlib directive makes it into the PBC file.