I'm troubleshooting a Perl script that unexpectedly hanging when it never hung before. I don't know Perl. I finally traced the problem to a file path string. This code works:
$eng_morph = "~/datafile.en.db";
tie %eng_morph, "DB_File", $eng_morph, O_CREAT|O_RDWR, 0664|| die "Cannot open dbmfile $eng_morph";
When I change the file name to include an underscore, the second line hangs forever:
$eng_morph = "~/datafile.en_us.db";
tie %eng_morph, "DB_File", $eng_morph, O_CREAT|O_RDWR, 0664|| die "Cannot open dbmfile $eng_morph";
Is there something wrong with the syntax? Is there any way to allow the underscores?
I'm using Ubuntu 14.04. Here's the uname output:
Linux asus-notebook 3.13.0-43-generic #72-Ubuntu SMP Mon Dec 8 19:35:06 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
Also, I'm also using the default Perl in the distro. Its version output is:
This is perl 5, version 18, subversion 2 (v5.18.2) built for x86_64-linux-gnu-thread-multi (with 41 registered patches, see perl -V for more detail)
This problem was intermittent. It turned out to be a threading problem -- as many intermittent problems are. The clue was the presence of an odd file in the output folder: "~/_db_datafile.en.db"
... or any defined output file name prefixed with "~/_db_"
. This output file ranged from 0 to 14K bytes when the desired output file should have been 2 or 3 megabytes. It looked like the Perl tie() function was interrupted while creating the DB file.
The code in question was being called from a Python script that used non-blocking threads with subprocess.Popen() piping. The Python script spawned the Perl script and continued its flow. While the Perl script was still creating the DB file, Python's non-blocked thread started piping data. This stopped the Perl script's file creation and caused a lockup.
The underscore in the file name was only the first intermittent instance of this error, and ultimately irrelevant to the problem.
Resolution was to simply create a while not os.path.exists(eng_morph):
loop in the Python code to pause until the proper DB file exists.