Hello -- While trying to debug an offsite-backup script, I found an odd bug in GNU tar related to the LANG environment variable: if LANG isn't set when I use tar to create a compressed archive, tar fails silently. That is, it doesn't write the archive and it exits with code 141 without any other indication that there was an error. (A session recording and version info are below.)
I tracked this down to the code in sys_child_open_for_compress() after the fork() that creates the child (gzip) process, but before the child runs exec() of gzip. Within this span, the child receives SIGSEGV, then the parent receives SIGPIPE when it tries to write data to the child. The SIGSEGV is caused by the call to gettext() (via the macro "_") at line 347 of system.c: set_program_name (_("tar (child)")); The same failure happens when untarring a compressed archive, although it's not a silent failure in that case. (See sample session, below.) That happens at the corresponding point in sys_child_open_for_uncompress(). I don't know whether there's a bug in gettext(), or a bug in the way gettext() is used here. I built a test-version of tar that omits the call to gettext(), passing the string directly to set_program_name(), and it behaves normally. I've worked around the problem by defining LANG in my offsite-backup script, so fixing this problem isn't urgent. Let me know if you need more info or if I can help by running other tests. Thanks. Jeremy Scofield jlscofi...@mac.com Seattle ========================== Details Follow ========================== VERSIONS Mac OS X 10.11.3 (El Capitan) GNU tar 1.28 (Built by the Macports facility. The only patches to the released sources seem to be in supporting Apple's extended attributes.) OTHER RANDOM OBSERVATIONS If I move the gettext() call to a spot before the fork(), there's no SIGSEGV. The forking appears to be necessary. If I add another identical call to gettext() in a spot before the fork(), there's no SIGSEGV at either call. Somehow a call before the fork() makes the later call safe. Maybe some kind of caching in gettext()? The version of GNU tar that I extracted from an old backup (1.17) doesn't exhibit this problem. SAMPLE SESSION (with comments added) $ ls # tar is GNU 1.28, otar is GNU 1.17, # ttar is GNU 1.28 with my test change otar testdir typescript tar ttar $ echo $LANG en_US.ISO8859-1 $ tar -cz -f 1.tgz testdir # This works as expected $ ls 1.tgz tar ttar otar testdir typescript $ tar -t -f 1.tgz # Ditto for untar testdir/ testdir/misc.c testdir/system.c testdir/xattrs.c $ unset LANG $ tar -cz -f 2.tgz testdir # This is the silent failure $ echo $? 141 # exit code 141 $ ls # archive wasn't created 1.tgz tar ttar otar testdir typescript $ tar -t -f 1.tgz # Similar problem with untar tar: Child died with signal 11 # but it's not silent tar: Error is not recoverable: exiting now $ ttar -cz -f 3.tgz testdir # Test version without call to gettext $ echo $? # exit code 0, archive created 0 $ ls 1.tgz otar testdir typescript 3.tgz tar ttar $ ttar -t -f 1.tgz # untar also works testdir/ testdir/misc.c testdir/system.c testdir/xattrs.c ================================ End ================================