At work, we encountered an error when interacting with child processes in an object’s destructor, and eventually traced it to the $? variable being overwritten during the wait calls. This happens after the call to exit(), so $? additionally meant our program’s return code to the operating system.
Specifically, the perldoc talked about this sort of error:
Inside an END subroutine $? contains the value that is going to be given to exit(). You can modify $? in an END subroutine to change the exit status of your program.
We don’t want that to happen, so we put a local $?=$?; inside of every END block. But now the programs return success to the OS while actually failing in their given task.
I managed to break it down into two sample programs. One that works as intended, and one that fails. This occurs on both v5.8.8 and v5.10.1 for x86_64-linux-thread-multi
Program A: (returns 0 to the operating system)
END{ local $?=$?; }
exit(100);
Program B: (returns 100 to the operating system)
END{ local $?=$?>>8; }
exit(100);
Why does it matter what value was assigned to the local $? in the end block?
Looks like a bug in perl. Apparently self assignment of
$?inlocalis broken:But this version works fine:
Pretty bizarre.
A bug report has been filed.