Skip Menu |

This queue is for tickets about the DBD-SQLite CPAN distribution.

Report information
The Basics
Id: 63873
Status: resolved
Priority: 0/
Queue: DBD-SQLite

People
Owner: Nobody in particular
Requestors: GUIDO [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Critical
Broken in: 1.31
Fixed in: (no value)



Subject: mod_perl and DBD::SQLite::db prepare failed: not an error
For the impatient: I will post a possible workaround in my next comment. The problem occurs on current Redhat systems, for example RHEL 5 or the CentOS equivalent but is probably not specific to Redhat. In brief, the reason for the behavior is that under mod_perl DBD::SQLite executes the sqlite3 functions mostly from /usr/lib64/libsqlite3.so.0 and not the built-in one. The symbol "sqlite_prepare_v2" however is not defined in the system-wide sqlite3.so.0 and therefore the built-in code is executed for that particular function. That mixtures wrecks havoc. In detail: These are the versions of the packages that take part in the problem: # rpm -q mod_perl httpd php php-mysql sqlite mod_perl-2.0.4-6.el5 httpd-2.2.3-43.el5 php-5.1.6-27.el5 php-mysql-5.1.6-27.el5 sqlite-3.3.6-5 When you start apache, it loads both mod_perl and mod_php5, and the latter is linked against libsqlite3.so.0: # lsof /usr/lib64/libsqlite3.so.0 COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME httpd 11665 root mem REG 8,2 373352 74214 /usr/lib64/libsqlite3.so.0.8.6 httpd 11667 apache mem REG 8,2 373352 74214 /usr/lib64/libsqlite3.so.0.8.6 etc. for the other preforked children. Now, when the symbols from DBD/SQLite.so are resolved by the dynamic linker, most of the code is already loaded via the system-wide sqlite3 (thanks to mod_php5). But "sqlite3_prepare_v2" was introduced after sqlite version 3.3.6, and therefore this particular symbol (and most probably others) are resolved from the built-in sqlite3.o (the one that ships with DBD-SQLite). I guess that this is not a Redhat problem but always occurs, when another apache module is linked against libsqlite3.so. The problem is visible only here because the installed sqlite shared library is so old. I tried to define SQLITE_API to "static" and SQLITE_EXTERN to the empty string in sqlite3.h. But that is not enough. You run into relocation problems, even if you compile everything with -fPIC. But if you want to address the problem in DBD-SQLite, that is probably the way to go. BTW, many thanks to Viktor Kojouharov and Slavi Agafonkin for analyzing the problem. I think that this ticket is in fact a duplicate or earlier ones. I still wanted to open a new one because it will help people find a solution. Sorry for that egoism. ;-)
As promised before, here are the possible workaround, if you are affected by the problem: 1) Disable mod_php5 if you can. 2) Install a recent sqlite3 version from http://www.sqlite.org/ and configure it with --prefix=/usr so that it will overwrite the slite3 that ships with your operating system. I haven't tried this option out myself, because the server is not mine, and overwriting the pre-installed sqlite3 will void the warranty by Redhat. Besides it could be dangerous because yum/rpm are linked against libsqlite3.so themselves. 3) a) Install a recent sqlite3 frm http://www.sqlite.org/ and install it in /usr/local. This is the default. b) Edit Makefile.PL in DBD-SQLite. Around line 127 you find a longer comment, and a conditional "if (0)". Change that into "if (1)". Now build the DBD-SQLite like this: perl Makefile.PL USE_LOCAL_SQLITE=0 SQLITE_LOCATION=/usr/local make sudo make install This will force SQLite.so to be linked against the version you compiled in 3a). This does actually not fix the problem but only hide it. Still, imho, this is the safest option until somebody comes up with a better workaround.
I think the easiest fix would be a trival patch to the embedded sqlite3.c and sqlite3.h: perl -pi -e s/^SQLITE_API /SQLITE_API dbd_/ sqlite3.c sqlite3.h Fixes the problem with mod_perl and doesn't hurt otherwise.
Am Mo 13. Dez 2010, 08:17:49, GUIDO wrote: Show quoted text
> I tried to define SQLITE_API to "static" and SQLITE_EXTERN to the empty > string in sqlite3.h. But that is not enough. You run into relocation > problems
Actually that approach works, I must have made a typo before. So, you have to add "-DSQLITE_EXTERN= -DSQLITE_API=static" to your CCFLAGS, and the problem should be fixed.
Show quoted text
> Actually that approach works, I must have made a typo before. So, you > have to add "-DSQLITE_EXTERN= -DSQLITE_API=static" to your CCFLAGS, and > the problem should be fixed.
And forgot to mention: Of course, you have to rename sqlite3.c to sqlite3.x (or whatever you want) and insert an #include "sqlite3.x" to dbdimp.c.
Sorry that I haven't responded to this ticket. DBD::SQLite 1.34_01 with a fix to this problem is out. If you still experience the same problem, please reopen this. Thanks.