Script continues running after an exit() call?

Script continues running after an exit() call?

am 15.06.2005 16:56:41 von Debo

I realize this post is going to be noninformative, but the script I'm
writing is rather long and so in the interest of brevity I'd like to just
summarize the problem I'm having.

I've written a script that, in general terms:

1. Opens a log file for writing, using Log:Log4Perl

1. Uses system() to call a program (NCBI BLAST) to associate the data in
two files. BLAST writes out a report of its activity. This report is quite
large (~600 megs).

2. Opens a handle to a postgres database (with AutoCommit off) using DBI.

3. Creates a cached INSERT query, and then parses the report, using this
query to insert lots (~20000) records based on this report. Some of the
insertions fail, but that doesn't really concern me because I sort of
expect the process to be lossy. (I don't know if this screws up the
ability to commit the changes).

4. Commits the changes to the database.

5. Uses the move() method of File::Copy to move the log file to a
different location.

6. Calls exit(0)

Now, here's the rub. The script will sometimes succeed or sometimes fail
to commit, which I think I can fix without much difficulty. However, when
I run this overnight and return in the morning, I INVARIABLY find about
18-20 perl processes running, and the BLAST command still running.

I look at the log that the script generates (in its new location, after
the move() call), and it seems that after the script reaches the exit(0),
it starts the BLAST process again, and continues to do so repeatedly. In
all, BLAST will be called and will complete execution about 3 or 4 times
throughout the course of the night, when the flow of control in the script
quite obviously shows that it should only execute once.

The thing I find especially strange is that the script continues to log
changes to the log file *after it has been moved*! It does this regardless
of whether I use the logger, or a plain filehandle to do my logging. The
script does not output anything pertaining to this problem on stderr (it's
mostly just some gunk that bioperl spits out for no particular reason).

So, I suppose my questions are:

1) Under what circumstances would perl be enticed to spawn a legion of
subprocesses without any explicit fork etc calls in the script?

2) How could these processes continue to write to a file after it has been
moved?

3) Why would a script 'ignore' an exit(0) call?

My platform right now is cygwin (shudder) with perl v5.8.5. I'd love
to be doing this in linux, but external forces have imposed the
environment and now i'm stuck with it.

Any tips you could provide that would help me diagnose the problem would be
appreciated.

Thanks!

-Debo

Re: Script continues running after an exit() call?

am 20.06.2005 12:20:03 von Joe Smith

Debo wrote:

> The thing I find especially strange is that the script continues to log
> changes to the log file *after it has been moved*!

That's not surprising at all. It happens all the time with *nix.

If process 1 has the log file open for writing when process 2
renames the log file, the file is still open for writing inspite
of the change in file name. That's why logrotate scripts often
send long-running daemons a signal when log files are renamed.
Upon receiving the signal, the daemon closes its log file and
re-opens it, which results in any further output being sent to
a new file.

By the way, are you aware that *nix allows logging to a file to
continue even when the file has been deleted? That's when you
want to use something like 'lsof' to verify what is still open
for output.

> Any tips you could provide that would help me diagnose the problem would be
> appreciated.

Beware of fork().
Send diagnostic print() statements to a separate log file, such as:
print DEBUG "About to start system(@command)\n";
system(@command);
print DEBUG "system() returned with an error code of $?\n";
...
print DEBUG "Time to exit(0)\n";
exit(0);


-Joe