1

I have some GDBM files created using an old 32-bit (i686) version of Perl (5.8.6) that I want to use with an x86_64 Perl 5.28.0, but it doesn't work. Here's my test code:

use strict;
use warnings;
use GDBM_File;

my $dbmfile = "/path/to/gdbm_test_file";
my %DBM;

eval {
    my $ok = tie(%DBM, 'GDBM_File', $dbmfile, &GDBM_WRCREAT, 0664);
    die "Error: Bad status!\n" unless $ok;
};
die "Error: Could not open $dbmfile.\n" if $@;

foreach my $key (sort(keys(%DBM))) {
    print "$key :: $DBM{$key}\n";
}
untie %DBM;

If I run this code with the older i686 Perl and $dbmfile pointing to a GDBM file recently created by the same i686 Perl, it correctly reads the GDBM file and prints out its contents.

If I run this code with x86_64 Perl 5.28.0, however, it just silently fails. No error. No output at all.

If I run this code with x86_64 Perl 5.10.1, the eval catches the "Bad status" error, and I get Error: Could not open /path/to/gdbm_test_file.

If I create a new GDBM file using x86_64 Perl 5.28.0 and try to read it with the old i686 Perl, i686 Perl dies with read error on the foreach line.

Platform: CentOS 6.8

gdbm.i686 and gdbm.x86_64 packages are both installed and both are the same version: 1.8.0-39

Any suggestions? Is this not possible?

Ed Sabol
  • 433
  • 4
  • 15
  • Just came across https://bugzilla.redhat.com/show_bug.cgi?id=162416 which indicates that 32-bit and 64-bit GDBM files are not interoperable across architectures. That seems like a crazy design decision to me. Any alternatives? – Ed Sabol Oct 15 '20 at 02:16
  • Just a side note: may be [sqlite](https://www.sqlite.org/) could be a good alternative for your task. – Polar Bear Oct 15 '20 at 23:09
  • Is there a `tie` interface for SQLite? – Ed Sabol Oct 17 '20 at 21:34
  • 1
    Check the following page - [SQLite_File](https://metacpan.org/pod/SQLite_File) – Polar Bear Oct 18 '20 at 04:00

1 Answers1

2

Given your comment about how 32-bit gdbm databases and 64-bit gdbm databases aren't compatible, I'd use a 32-bit version of the gdbm_dump utility to dump the database to a flat file, and then feed it to a 64-bit version of gdbm_load to re-create the database so it can be read by the 64-bit perl gdbm library.

You might have to build these from source to get the appropriate versions depending on what packages CentOS provides - I'm not familiar with it.


Alternatively, write a quick tool using the 32-bit version of perl to read the 32-bit gdbm database and convert it to a different dbm that doesn't suffer from the same problem so both 32-bit and 64-bit programs can use the same file.

Psuedocode:

tie my %gdbm, 'GDBM_File', 'olddb.gdbm', read-only options;
tie my %other, 'Other_DBM', 'newdb.whatever', write/create options;
while (my ($key, $value) = each %gdbm) {
    $other{$key} = $value;
}
untie %gdbm;
untie %other;
Shawn
  • 47,241
  • 3
  • 26
  • 60
  • If there's another xDBM that supports architecture interoperability, I'd like to know what it is. NDBM and DBM are just GDBM under the hood on Linux, AFAIK. – Ed Sabol Oct 15 '20 at 22:27
  • 1
    @EdSabol I'd look into LMDB, Berkeley DB, and Kyoto Cabinet at the very least. – Shawn Oct 15 '20 at 22:33
  • LDBM is memory-only. I need a file for interoperability. And I can’t find a `tie` interface for Kyotocabinet. Is there a list of Perl modules that work with `tie` somewhere? – Ed Sabol Oct 17 '20 at 21:33
  • 1
    @EdSabol **LMDB** is file based (Though I think it's more common to give it a directory to make multiple files in). And see https://dbmx.net/kyotocabinet/perldoc/#tying_functions_of_kyotocabinet__db – Shawn Oct 17 '20 at 22:06