Patchwork [RFC,6/6] tests: Workaround gcov being unable to open .gcda file

login
register
mail settings
Submitter Eduardo Habkost
Date Jan. 28, 2013, 5:59 p.m.
Message ID <20130128175905.GC6849@otherpad.lan.raisama.net>
Download mbox | patch
Permalink /patch/216285/
State New
Headers show

Comments

Eduardo Habkost - Jan. 28, 2013, 5:59 p.m.
On Mon, Jan 28, 2013 at 03:26:36PM -0200, Eduardo Habkost wrote:
> On Sat, Jan 26, 2013 at 12:45:15PM +0100, Andreas Färber wrote:
> > Resolve the following error:
> > 
> >   hw/tmp105.gcda:cannot open data file, assuming not executed
> > 
> > by adding a sleep before running gcov after the qtest cases.
> 
> Do you understand why exactly this happens?

I believe I understand what's happening. See the strace output at the
end of this message.

* tmp105-test exits before QEMU exits, because the wait4() call fails.
* the wait4() call fails because there's another process already waiting for
  the QEMU process (7263)
* The process that is already waiting for QEMU is the child created to
  run system()

qtest_quit() is incorrectly waiting for the QEMU PID directly instead of
saving the pid from the fork() call at qtest_init(). Experimental fix:




-------------------------

PIDs on the strace output below:

 7254: make
 7259: shell process created by make
 7260, 7262: gtester
 7261: tests/tmp105-test
 7263: the child process created by qtest_init() to run system()
 7264: QEMU


7254  15:36:19.212328 execve("/usr/bin/make", ["make", "check-qtest-arm"], [/* 65 vars */]) = 0
7259  15:36:21.726961 execve("/bin/sh", ["/bin/sh", "-c", "echo \"GTESTER check-qtest-arm\" &"...], [/* 69 vars */] <unfinished ...>
7259  15:36:21.727490 <... execve resumed> ) = 0
7254  15:36:21.727517 wait4(-1,  <unfinished ...>
7259  15:36:21.738632 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f4f3017ba10) = 7260
7259  15:36:21.739563 wait4(-1,  <unfinished ...>
7260  15:36:21.739712 execve("/usr/bin/gtester", ["gtester", "-k", "-q", "-m=quick", "tests/tmp105-test"], [/* 69 vars */]) = 0
7260  15:36:21.744830 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f10a4d3ea10) = 7261
7261  15:36:21.745167 rt_sigaction(SIGTERM, {SIG_DFL, [TERM], SA_RESTORER|SA_RESTART, 0x3433e35c20}, {SIG_DFL, [], 0}, 8) = 0
7261  15:36:21.745769 execve("tests/tmp105-test", ["tests/tmp105-test", "--quiet", "--keep-going", "-m=quick", "--GTestLogFD=5"], [/* 69 vars */] <unfinished ...>
7260  15:36:21.746685 clone(child_stack=0x7f10a4d3cfb0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f10a4d3d9d0, tls=0x7f10a4d3d700, child_tidptr=0x7f10a4d3d9d0) = 7262
7260  15:36:21.746813 wait4(7261, 0xe76664, WNOHANG, NULL) = 0
7261  15:36:21.746886 <... execve resumed> ) = 0
7261  15:36:21.776429 clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fa1e0996b50) = 7263
7263  15:36:21.776975 clone( <unfinished ...>
7263  15:36:21.777228 <... clone resumed> child_stack=0, flags=CLONE_PARENT_SETTID|SIGCHLD, parent_tidptr=0x7fff6f5439e0) = 7264
7263  15:36:21.777249 wait4(7264,  <unfinished ...>

                            ^^^^ HERE


7264  15:36:21.777315 execve("/bin/sh", ["sh", "-c", "arm-softmmu/qemu-system-arm -qte"...], [/* 69 vars */]) = 0
7264  15:36:21.781756 execve("arm-softmmu/qemu-system-arm", ["arm-softmmu/qemu-system-arm", "-qtest", "unix:/tmp/qtest-7261.sock,nowait", "-qtest-log", "/dev/null", "-qmp", "unix:/tmp/qtest-7261.qmp,nowait", "-pidfile", "/tmp/qtest-7261.pid", "-machine", "accel=qtest", "-display", "none", "-machine", "n800"], [/* 69 vars */]) = 0
7264  15:36:21.852206 clone(child_stack=0x7f39d6424fb0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f39d64279d0, tls=0x7f39d6427700, child_tidptr=0x7f39d64279d0) = 7265
7260  15:36:22.107937 write(-1, "      <status exit-status=\"0\" n-"..., 61 <unfinished ...>
7261  15:36:22.107964 kill(7264, SIGTERM <unfinished ...>
7261  15:36:22.108004 wait4(7264,  <unfinished ...>

                            ^^^^ HERE

7264  15:36:22.108016 --- SIGTERM {si_signo=SIGTERM, si_code=SI_USER, si_pid=7261, si_uid=500} ---
7261  15:36:22.108026 <... wait4 resumed> 0x7fff6f543bb0, 0, NULL) = -1 ECHILD (No child processes)

                                                                        ^^^^^ HERE

7261  15:36:22.110356 exit_group(0)     = ?
7261  15:36:22.110895 +++ exited with 0 +++
7262  15:36:22.111276 wait4(7261,  <unfinished ...>
7262  15:36:22.111330 <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG, NULL) = 7261
7260  15:36:22.111732 exit_group(0)     = ?
7262  15:36:22.112003 +++ exited with 0 +++
7260  15:36:22.112039 +++ exited with 0 +++
7259  15:36:22.112054 <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 7260
7259  15:36:22.112148 wait4(-1, 0x7fff8369b458, WNOHANG, NULL) = -1 ECHILD (No child processes)
7259  15:36:22.112276 exit_group(0)     = ?
7259  15:36:22.112455 +++ exited with 0 +++
7254  15:36:22.112469 <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 7259
7266  15:36:22.112723 execve("/bin/sh", ["/bin/sh", "-c", "for f in hw/tmp105.c; do echo Gc"...], [/* 69 vars */] <unfinished ...>
7254  15:36:22.113039 wait4(-1,  <unfinished ...>
7266  15:36:22.113071 <... execve resumed> ) = 0
7266  15:36:22.118874 clone( <unfinished ...>
7266  15:36:22.119074 <... clone resumed> child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f5f3ebc3a10) = 7267
7267  15:36:22.121522 clone( <unfinished ...>
7267  15:36:22.121738 <... clone resumed> child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f5f3ebc3a10) = 7268
7267  15:36:22.122143 wait4(-1,  <unfinished ...>
7268  15:36:22.122185 execve("/usr/bin/dirname", ["dirname", "hw/tmp105.c"], [/* 68 vars */] <unfinished ...>
7268  15:36:22.122449 <... execve resumed> ) = 0
7268  15:36:22.124550 exit_group(0)     = ?
7268  15:36:22.124617 +++ exited with 0 +++
7267  15:36:22.124642 <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 7268
7267  15:36:22.124738 wait4(-1,  <unfinished ...>
7267  15:36:22.124757 <... wait4 resumed> 0x7fffe5bd1c98, WNOHANG, NULL) = -1 ECHILD (No child processes)
7267  15:36:22.124937 exit_group(0)     = ?
7267  15:36:22.125044 +++ exited with 0 +++
7266  15:36:22.125103 wait4(-1, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], WNOHANG, NULL) = 7267
7266  15:36:22.125139 wait4(-1, 0x7fffe5bd1ed8, WNOHANG, NULL) = -1 ECHILD (No child processes)
7266  15:36:22.127367 clone( <unfinished ...>
7266  15:36:22.127440 <... clone resumed> child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f5f3ebc3a10) = 7269
7266  15:36:22.127696 wait4(-1,  <unfinished ...>
7269  15:36:22.127799 execve("/usr/bin/gcov", ["gcov", "-n", "hw/tmp105.c", "-o", "hw"], [/* 68 vars */] <unfinished ...>
7269  15:36:22.128101 <... execve resumed> ) = 0
7269  15:36:22.131524 open("hw/tmp105.gcda", O_RDONLY) = -1 ENOENT (No such file or directory)
7269  15:36:22.131582 write(2, "hw/tmp105.gcda:cannot open data "..., 60 <unfinished ...>
7269  15:36:22.132133 exit_group(0)     = ?
7269  15:36:22.132256 +++ exited with 0 +++
7266  15:36:22.132275 <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 7269
7266  15:36:22.132477 wait4(-1,  <unfinished ...>
7266  15:36:22.132515 <... wait4 resumed> 0x7fffe5bd2158, WNOHANG, NULL) = -1 ECHILD (No child processes)
7266  15:36:22.132849 exit_group(0)     = ?
7266  15:36:22.133008 +++ exited with 0 +++
7254  15:36:22.133047 <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 7266
7254  15:36:22.136606 exit_group(0)     = ?
7254  15:36:22.138357 +++ exited with 0 +++
7264  15:36:22.319413 open("/home/ehabkost/pessoal/proj/virt/qemu/hw/tmp105.gcda", O_RDWR|O_CREAT, 0666) = 12
7264  15:36:22.419748 exit_group(0)     = ?
7265  15:36:22.420963 +++ exited with 0 +++
7264  15:36:22.451257 +++ exited with 0 +++
7263  15:36:22.451328 <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0, NULL) = 7264
7263  15:36:22.453877 exit_group(0)     = ?
7263  15:36:22.454612 +++ exited with 0 +++

> 
> > 
> > Signed-off-by: Andreas Färber <afaerber@suse.de>
> > ---
> >  tests/Makefile |    2 +-
> >  1 Datei geändert, 1 Zeile hinzugefügt(+), 1 Zeile entfernt(-)
> > 
> > diff --git a/tests/Makefile b/tests/Makefile
> > index 442b286..3182dca 100644
> > --- a/tests/Makefile
> > +++ b/tests/Makefile
> > @@ -153,7 +153,7 @@ $(patsubst %, check-qtest-%, $(QTEST_TARGETS)): check-qtest-%: $(check-qtest-y)
> >  	$(if $(CONFIG_GCOV),@rm -f *.gcda */*.gcda */*/*.gcda */*/*/*.gcda,)
> >  	$(call quiet-command,QTEST_QEMU_BINARY=$*-softmmu/qemu-system-$* \
> >  		gtester $(GTESTER_OPTIONS) -m=$(SPEED) $(check-qtest-$*-y),"GTESTER $@")
> > -	$(if $(CONFIG_GCOV),@for f in $(gcov-files-$*-y); do \
> > +	$(if $(CONFIG_GCOV),@sleep 1; for f in $(gcov-files-$*-y); do \
> >  	  echo Gcov report for $$f:;\
> >  	  $(GCOV) $(GCOV_OPTIONS) $$f -o `dirname $$f`; \
> >  	done,)
> > -- 
> > 1.7.10.4
> > 
> > 
> 
> -- 
> Eduardo
>

Patch

diff --git a/tests/libqtest.c b/tests/libqtest.c
index 913fa05..4c151cd 100644
--- a/tests/libqtest.c
+++ b/tests/libqtest.c
@@ -40,6 +40,7 @@  struct QTestState
     bool irq_level[MAX_IRQ];
     GString *rx;
     gchar *pid_file;
+    int child_pid;
     char *socket_path, *qmp_socket_path;
 };
 
@@ -144,6 +145,7 @@  QTestState *qtest_init(const char *extra_args)
 
     s->rx = g_string_new("");
     s->pid_file = pid_file;
+    s->child_pid = pid;
     for (i = 0; i < MAX_IRQ; i++) {
         s->irq_level[i] = false;
     }
@@ -165,8 +167,9 @@  void qtest_quit(QTestState *s)
 
     pid_t pid = qtest_qemu_pid(s);
     if (pid != -1) {
-        kill(pid, SIGTERM);
-        waitpid(pid, &status, 0);
+        kill(pid, SIGTERM);                /* kill QEMU */
+        waitpid(s->child_pid, &status, 0); /* but wait for the child created to
+                                            * run system() */
     }
 
     unlink(s->pid_file);