petdance/scratch — Issue #216: Parrot may end up calling dlclose() twice with the same handle, ref. t/pmc/threads.t test 14
Author: petdance
Created: 2011-11-14 06:07:18+00:00
State: open
Labels: bug, Pri-normal, Sev-medium

I have been puzzled by why the last test in t/pmc/threads.t (number 14 at last count) fails on all the NetBSD systems I'm testing on.
It turns out that the reason is that this particular test causes parrot to call dlclose() twice with the same handle value, and ld.elf_so has a check for whether the given handle is "valid", which it isn't in the second instance, causing spurious output from the test, which in turns causes the test to fail, like so:

```
not ok 14 - CLONE_CODE|CLONE_GLOBALS|CLONE_HLL|CLONE_LIBRARIES - TT \# 1250
# Failed test 'CLONE_CODE|CLONE_GLOBALS|CLONE_HLL|CLONE_LIBRARIES - TT \# 1250'
# at t/pmc/threads.t line 831.
# got: 'in thread:
# 0
# ok (equal)
# 42
# in main:
# 0
# ok (equal)
# 42
# Invalid shared object handle 0xeffed600
# '
# expected: 'in thread:
# 0
# ok (equal)
# 42
# in main:
# 0
# ok (equal)
# 42
# '
# Looks like you failed 1 test of 14.
```

The following GDB session shows that this is the problem:

```
granny-smith: {130} gdb ./parrot
GNU gdb 6.5
Copyright (C) 2006 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB. Type "show warranty" for details.
This GDB was configured as "powerpc--netbsd"...
(gdb) b dlclose
Function "dlclose" not defined.
Make breakpoint pending on future shared library load? (y or [n]) y

Breakpoint 1 (dlclose) pending.
(gdb) r t/pmc/threads_14.pir
Starting program: /usr/users/he/parrot/parrot t/pmc/threads_14.pir
Breakpoint 2 at 0xefff594c
Pending breakpoint "dlclose" resolved
in thread:
0
ok (equal)
42

Breakpoint 2, 0xefff594c in dlclose () from /usr/libexec/ld.elf_so
(gdb) where
#0 0xefff594c in dlclose () from /usr/libexec/ld.elf_so
#1 0xefd65f30 in Parrot_dlclose (handle=0xeffed600)
at config/gen/platform/generic/dl.c:96
#2 0xefe6e274 in Parrot_ParrotLibrary_destroy (interp=0xee8031e0,
pmc=0xee7d3e60) at ./src/pmc/parrotlibrary.pmc:65
#3 0xefd6a204 in Parrot_pmc_destroy (interp=0xee8031e0, pmc=0xee7d3e60)
at src/pmc.c:116
#4 0xefd092d0 in free_pmc_in_pool (interp=0xee8031e0, pool_unused=0xee710150,
p=0xee7d3e60) at src/gc/mark_sweep.c:602
#5 0xefd083d8 in Parrot_gc_sweep_pool (interp=0xee8031e0, pool=0xee710150)
at src/gc/mark_sweep.c:331
#6 0xefd071f0 in gc_ms_finalize (interp=0xee8031e0, mem_pools=0xee807f60)
at src/gc/gc_ms.c:232
#7 0xefd07490 in gc_ms_mark_and_sweep (interp=0xee8031e0, flags=4)
at src/gc/gc_ms.c:161
#8 0xefd03e74 in Parrot_gc_mark_and_sweep (interp=0xee8031e0, flags=4)
at src/gc/api.c:856
#9 0xefd1aab8 in Parrot_really_destroy (interp=0xee8031e0,
exit_code_unused=0, arg_unused=0x0) at src/interp/inter_create.c:337
#10 0xefd79e58 in pt_thread_join (parent=0xee803100, tid=1)
at src/thread.c:1383
#11 0xeff16fc8 in Parrot_ParrotRunningThread_nci_join (interp=0xee803100,
pmc=0xee8afbac) at ./src/pmc/parrotrunningthread.pmc:108
#12 0xefe7d4a0 in Parrot_NCI_invoke (interp=0xee803100, pmc=0xee8afbac,
next=0xee7193d0) at ./src/pmc/nci.pmc:338
#13 0xefc5719c in Parrot_callmethodcc_p_sc (cur_opcode=0xee7193c4,
interp=0xee803100) at src/ops/object.ops:74
#14 0xefd6e3f4 in runops_slow_core (interp=0xee803100, runcore=0xee8ee5c0,
pc=0xee7193c4) at src/runcore/cores.c:848
#15 0xefd6bae8 in runops_int (interp=0xee803100, offset=64)
at src/runcore/main.c:546
#16 0xefd1c8bc in runops (interp=0xee803100, offs=64) at src/call/ops.c:99
#17 0xefd1225c in Parrot_pcc_invoke_from_sig_object (interp=0xee803100,
sub_obj=0xee8b1d94, call_object=0xee8b1dbc) at src/call/pcc.c:297
#18 0xefd123c4 in Parrot_pcc_invoke_sub_from_c_args (interp=0xee803100,
sub_obj=0xee8b1d94, sig=0xeff83ea0 "P->") at src/call/pcc.c:76
#19 0xefceba2c in Parrot_runcode (interp=0xee803100, argc=1, argv=0xffffd870)
at src/embed.c:825
#20 0xeff51a58 in imcc_run_pbc (interp=0xee803100, obj_file=0,
output_file=0x0, argc=1, argv=0xffffd870) at compilers/imcc/main.c:790
#21 0xeff51e10 in imcc_run (interp=0xee803100,
sourcefile=0xffffe998 "t/pmc/threads_14.pir", argc=1, argv=0xffffd870)
at compilers/imcc/main.c:1073
#22 0x01800be8 in main (argc=1, argv=0xffffd870) at src/main.c:60
(gdb) c
Continuing.
in main:
0
ok (equal)
42

Breakpoint 2, 0xefff594c in dlclose () from /usr/libexec/ld.elf_so
(gdb) where
#0 0xefff594c in dlclose () from /usr/libexec/ld.elf_so
#1 0xefd65f30 in Parrot_dlclose (handle=0xeffed600)
at config/gen/platform/generic/dl.c:96
#2 0xefe6e274 in Parrot_ParrotLibrary_destroy (interp=0xee803100,
pmc=0xee8e5ec4) at ./src/pmc/parrotlibrary.pmc:65
#3 0xefd6a204 in Parrot_pmc_destroy (interp=0xee803100, pmc=0xee8e5ec4)
at src/pmc.c:116
#4 0xefd092d0 in free_pmc_in_pool (interp=0xee803100, pool_unused=0xee84c150,
p=0xee8e5ec4) at src/gc/mark_sweep.c:602
#5 0xefd083d8 in Parrot_gc_sweep_pool (interp=0xee803100, pool=0xee84c150)
at src/gc/mark_sweep.c:331
#6 0xefd071f0 in gc_ms_finalize (interp=0xee803100, mem_pools=0xee807080)
at src/gc/gc_ms.c:232
#7 0xefd07490 in gc_ms_mark_and_sweep (interp=0xee803100, flags=4)
at src/gc/gc_ms.c:161
#8 0xefd03e74 in Parrot_gc_mark_and_sweep (interp=0xee803100, flags=4)
at src/gc/api.c:856
#9 0xefd1aab8 in Parrot_really_destroy (interp=0xee803100,
exit_code_unused=0, arg_unused=0x0) at src/interp/inter_create.c:337
#10 0xefcf1038 in Parrot_exit (interp=0xee803100, status=0) at src/exit.c:90
#11 0x01800c04 in main (argc=1, argv=0xffffd870) at src/main.c:65
(gdb) c
Continuing.
Invalid shared object handle 0xeffed600

Program exited normally.
(gdb)
```

Note that the handle= value in the call preceding dlclose() is the same in the two cases.

Parrot should not be calling dlclose() with the same handle value in a row, without the second one being the result of a dlopen(), which isn't the case here. OK, that's not proven by the above, but this one does:

```
(gdb) b dlopen
Breakpoint 3 at 0xefff5d60
(gdb) r
Starting program: /usr/users/he/parrot/parrot t/pmc/threads_14.pir
...
Breakpoint 3, 0xefff5d60 in dlopen () from /usr/libexec/ld.elf_so
(gdb) c
Continuing.
in thread:
0
ok (equal)
42

Breakpoint 2, 0xefff594c in dlclose () from /usr/libexec/ld.elf_so
(gdb) c
Continuing.
in main:
0
ok (equal)
42

Breakpoint 2, 0xefff594c in dlclose () from /usr/libexec/ld.elf_so
(gdb) c
Continuing.
Invalid shared object handle 0xeffed600

Program exited normally.
(gdb)
```

Originally http://trac.parrot.org/parrot/ticket/1340