Opened 13 years ago

Closed 13 years ago

#522 closed defect (fixed)

Search::Xapian Perl module should specify RTLD_GLOBAL in dlopen call

Reported by: David F. Skoll Owned by: Olly Betts
Priority: normal Milestone: 1.0.23
Component: Search::Xapian Version: 1.2.3
Severity: normal Keywords:
Cc: Blocked By:
Blocking: Operating System: All

Description (last modified by Olly Betts)

If you're using Search::Xapian as well as other C++ code that links against libxapian.so, C++ exceptions mysteriously fail because the weak symbols in each .so don't match, so the C++ runtime cannot identify the types of the exceptions.

A simple one-line patch to Xapian.pm fixes the problem:

diff --git a/Xapian.pm b/Xapian.pm
index 643edc1..d071721 100644
--- a/Xapian.pm
+++ b/Xapian.pm
@@ -38,6 +38,11 @@ require DynaLoader;
 
 our @ISA = qw(DynaLoader);
 
+# We need to use the RTLD_GLOBAL flag to dlopen() so that other C++
+# modules that link against libxapian.so get the *same* value for all the
+# weak symbols (eg, the exception classes)
+sub dl_load_flags { 0x01 }
+
 # This allows declaration      use Search::Xapian ':all';
 # If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
 # will save memory.

Attachments (2)

xapian.patch (539 bytes ) - added by David F. Skoll 13 years ago.
Simple patch to Xapian.pm to pass RTLD_GLOBAL to dlopen() in DynaLoader
xapian-dlopen-fix-with-test-case.patch (8.6 KB ) - added by David F. Skoll 13 years ago.
Test case illustrating dlopen problem.

Download all attachments as: .zip

Change History (7)

by David F. Skoll, 13 years ago

Attachment: xapian.patch added

Simple patch to Xapian.pm to pass RTLD_GLOBAL to dlopen() in DynaLoader

comment:1 by Olly Betts, 13 years ago

Component: OtherSearch::Xapian
Description: modified (diff)
Milestone: 1.2.4
Status: newassigned

Thanks for the patch.

It would be good to make sure this fix works on all platforms, and that it continues to work. How feasible is it to write a regression test?

I guess we'd need a second Perl module which links to xapian-core and to throw an exception and see if we can catch it, or something like that?

comment:2 by David F. Skoll, 13 years ago

Hi,

Give me a couple of days... I'll try to work up a test case.

Regards,

David.

by David F. Skoll, 13 years ago

Test case illustrating dlopen problem.

comment:3 by David F. Skoll, 13 years ago

Hi,

My colleague Dave O'Neill came up with the test case in the attachment xapian-dlopen-fix-with-test-case.patch

Unfortunately, running the test is a bit ugly. You have to do this:

# Build Xapian
perl Makefile.PL && make

# Run our test specifically
cd t/ticket-522 && make && make test

The "make test" in t/ticket-522 fails on Debian GNU Linux 5.0 (Lenny) if the sub dl_load_flags { 0x01 } line is commented out, but succeeds if it is present.

Regards,

David.

comment:4 by Olly Betts, 13 years ago

Milestone: 1.2.41.0.23
Version: 1.2.3

Great, thanks - I've hacked the testcase around and managed to get it to run fairly sanely as part of "make test" from the main project, and committed this to trunk in r15215.

The fix itself is simple and seems safe, so we should certainly backport the fix to 1.0.x (not so sure about the testcase!), so setting the milestone appropriately.

comment:5 by Olly Betts, 13 years ago

Resolution: fixed
Status: assignedclosed

OK, backported to 1.0 in r15217. The test worked with just needing to change the exception name (1.0 throws DatabaseCreateError instead of DatabaseOpeningError here) so I backported that too.

Note: See TracTickets for help on using tickets.