bug#27532: getprogname: support for qemu
On Thu, Jun 29, 2017 at 9:50 AM, Assaf Gordon wrote: > Hello Bruno and all, > >> On Jun 29, 2017, at 12:26, Bruno Haible wrote: >> ... > Luckily, many GNU test scripts already use "$prog" perl variable > for the program's name in error message, so perhaps it would be possible > to accomodate qemu without code changes. > > I've encountered the same for my program (datamash). > and as an ugly hack added an undocumented option to print the program's name > to set '$prog' accordingly: > https://git.savannah.gnu.org/cgit/datamash.git/tree/tests/datamash-tests.pl#n37 > ## Cross-Compiling portability hack: > ## under qemu/binfmt, argv[0] (which is used to report errors) will contain > ## the full path of the binary, if the binary is on the $PATH. > ## So we try to detect what is the actual returned value of the program > ## in case of an error. > my $prog = `$prog_bin ---print-progname`; > $prog = $prog_bin unless $prog; > > > But this hack can be avoided, if we just run 'grep' with invalid > arguments, triggering an error, then extracting the program name from STDERR. > > E.g. for > https://git.savannah.gnu.org/cgit/grep.git/tree/tests/filename-lineno.pl > change the following on line 26 from: > my $prog = 'grep'; > to > my $prog = 'grep'; > my $full_prog_name = `$prog --invalid-option-for-testing 2>&1 | head -n1 > | cut -f1 -d:`; > $prog = $full_prog_name if $full_prog_name; > > This is untested code, but should work more-or-less. > Once "$prog" is updated, all the tests should pass. Thanks to both of you. Does this patch solve the problem? From d86483b0c4be5298c96ccaaa62670a04b018af42 Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Thu, 29 Jun 2017 18:06:11 -0700 Subject: [PATCH] tests: avoid false failure when run in qemu user mode * tests/filename-lineno.pl: Derive the program name that grep will use in diagnostics, based on a suggestion from Assaf Gordon. Reported by Bruno Haible in http://bugs.gnu.org/27532 --- tests/filename-lineno.pl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/filename-lineno.pl b/tests/filename-lineno.pl index 8eead57..6cc86b7 100755 --- a/tests/filename-lineno.pl +++ b/tests/filename-lineno.pl @@ -24,6 +24,9 @@ use strict; (my $program_name = $0) =~ s|.*/||; my $prog = 'grep'; +my $full_prog_name = `$prog --no-such-option 2>&1`; +$full_prog_name =~ s/:.*//s; +$prog = $full_prog_name if $full_prog_name; # Turn off localization of executable's output. @ENV{qw(LANGUAGE LANG LC_ALL)} = ('C') x 3; -- 2.13.0
bug#27532: getprogname: support for qemu
Hello Bruno and all, > On Jun 29, 2017, at 12:26, Bruno Haible wrote: > > When running the testsuite of grep-3.0 with qemu user mode, some tests fail. > [...] > *** 1 > ! grep: g:4: Unmatched [... > --- 1 > ! /tmp/grep-3.0/build-arm64/src/grep: g:4: Unmatched [... > [...] > argv[0] = absolute file name of qemu-aarch64 > argv[1] = absolute file name of grep (it must be absolute, since it's not > qemu's job to search for 'grep' in $PATH). Luckily, many GNU test scripts already use "$prog" perl variable for the program's name in error message, so perhaps it would be possible to accomodate qemu without code changes. I've encountered the same for my program (datamash). and as an ugly hack added an undocumented option to print the program's name to set '$prog' accordingly: https://git.savannah.gnu.org/cgit/datamash.git/tree/tests/datamash-tests.pl#n37 ## Cross-Compiling portability hack: ## under qemu/binfmt, argv[0] (which is used to report errors) will contain ## the full path of the binary, if the binary is on the $PATH. ## So we try to detect what is the actual returned value of the program ## in case of an error. my $prog = `$prog_bin ---print-progname`; $prog = $prog_bin unless $prog; But this hack can be avoided, if we just run 'grep' with invalid arguments, triggering an error, then extracting the program name from STDERR. E.g. for https://git.savannah.gnu.org/cgit/grep.git/tree/tests/filename-lineno.pl change the following on line 26 from: my $prog = 'grep'; to my $prog = 'grep'; my $full_prog_name = `$prog --invalid-option-for-testing 2>&1 | head -n1 | cut -f1 -d:`; $prog = $full_prog_name if $full_prog_name; This is untested code, but should work more-or-less. Once "$prog" is updated, all the tests should pass. Hope this helps, regards, - assaf
bug#27532: grep test failures under qemu
Oops, the title was wrong. Corrected subject: "grep test failures under qemu"
bug#27532: getprogname: support for qemu
Hi, When running the testsuite of grep-3.0 with qemu user mode, some tests fail. How to reproduce: - On a Debian or Ubuntu system, install package 'g++-5-aarch64-linux-gnu'. - Install qemu-2.8.1 or qemu-2.9.0 from source. - Prepare for executing aarch64 binaries: $ sudo update-binfmts --install qemu-aarch64 $HOME/inst-qemu/2.8.1/bin/qemu-aarch64 --magic '\x7f\x45\x4c\x46\x02\x01\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\x00\xb7\x00' --mask '\xff\xff\xff\xff\xff\xff\xff\x00\xff\xff\xff\xff\xff\xff\xff\xff\xfe\xff\xff\xff' --offset 0 --credential no $ QEMU_LD_PREFIX=/usr/aarch64-linux-gnu; export QEMU_LD_PREFIX - $ ../configure --host=aarch64-linux CC="aarch64-linux-gnu-gcc-5" - $ make - $ make check Test failure example: filename-lineno.pl: test invalid-re: stderr mismatch, comparing invalid-re.1 (expected) and invalid-re.E (actual) *** invalid-re.1Thu Jun 29 17:40:54 2017 --- invalid-re.EThu Jun 29 17:40:54 2017 *** *** 1 ! grep: g:4: Unmatched [... --- 1 ! /tmp/grep-3.0/build-arm64/src/grep: g:4: Unmatched [... How come? The test suite invokes 'grep' from $PATH but: 1) When the x86_64 kernel is about to execute a native aarch64 binary, it prepares an argv with argv[0] = absolute file name of qemu-aarch64 argv[1] = absolute file name of grep (it must be absolute, since it's not qemu's job to search for 'grep' in $PATH). 2) Inside grep, which is linked to glibc, the error() function used is the one from glibc. The one from gnulib, present in grep's source code, is not compiled. The error() function in glibc uses program_invocation_name, which is the absolute path of 'grep' by (1). The error() function in glibc does *not* use program_invocation_short_name, nor does it use gnulib's getprogname() which would also return program_invocation_short_name. The following proof-of-concept patch fixes the problem - "make check" passes -, but I don't know whether - you want something like this at all, - you want to limit it to the test situation. i.e. make the behaviour depend on some environment variable, - you prefer to fix the test suite instead (by removing the dirname of the program from the output before comparison with the expected result). Bruno --- grep-3.0/src/grep.c.bak 2017-02-09 02:37:33.0 +0100 +++ grep-3.0/src/grep.c 2017-06-29 18:07:53.072178500 +0200 @@ -2432,6 +2432,15 @@ return result; } +#if __GLIBC__ >= 2 +extern void (*error_print_progname) (void); +static void +error_print_program_invocation_short_name (void) +{ + fprintf (stderr, "%s: ", program_invocation_short_name); +} +#endif + int main (int argc, char **argv) { @@ -2445,6 +2454,10 @@ int fread_errno; intmax_t default_context; FILE *fp; + +#if __GLIBC__ >= 2 + error_print_progname = error_print_program_invocation_short_name; +#endif exit_failure = EXIT_TROUBLE; initialize_main (&argc, &argv);