[Nut-upsdev] git stable, cppunit?

Greg Troxel gdt at lexort.com
Mon Dec 2 14:35:06 GMT 2024


Progress!  With "if EINTR, continue", the usual idiom for using select,
the tests run.

Then, I got:

  $ ./cppunittest
  D: Getting test suite...
  D: Preparing test runner...
  D: Setting test runner outputter...
  D: Launching the test run...
  .................................F.

  nutipc_ut.cpp:259:Assertion
  Test name: NutIPCUnitTest::testSignalRecvQuick
  assertion failed
  - Expression: caught_signals.size() == 5

  Failures !!!
  Run: 34   Failure total: 1   Failures: 1   Errors: 0
  D: Got to the end of test suite with code 'false'

which is not a pass, but much better.

Running it under ktrace, it almost always passes.

However, the core premise of the test seems off.  If there are multiple
kill calls with the same signal I'm 99% sure POSIX is fine with a single
entry into the handler if the signal from kill call#1 was not delivered
before the same signal was sent by call#2.  signals are not messages;
they are a software version of hardware interrupts.

After a bunch of runs, I got a failure while being traced:

   27766  27766 cppunittest 1733148881.022508648 CALL  kill(0x6c76, SIGUSR1)
   27766  27766 cppunittest 1733148881.022531398 RET   kill 0
   27766  27766 cppunittest 1733148881.022554065 CALL  kill(0x6c76, SIGUSR2)
   27766  27766 cppunittest 1733148881.022576731 RET   kill 0

two signals sent rapidly

   27766  24847 cppunittest 1733148881.022599356 RET   __select50 -1 errno 4 Interrupted system call

Select bails out (before the handler is going to be invoked, I think).
This is only 91 us after the first kill is recorded in ktrace.

   27766  27766 cppunittest 1733148881.022712606 CALL  kill(0x6c76, SIGUSR2)

killer proc calls into kill again, only 200 us later.  Perhaps it is
waiting for a lock, perhaps it determines that the signal is already
queued so there's nothing to do.  It's legit for the OS to defer signal
delivery until the process being signaled gets scheduled, I think.
Can't be a long time, but I don't think you can complain about less than
a clock tick.

   27766  24847 cppunittest 1733148881.022735272 PSIG  SIGUSR1 caught handler=0x48556c mask=(): code=SI_USER sent by pid=27766, uid=10853)
   27766  24847 cppunittest 1733148881.022791897 PSIG  SIGUSR2 caught handler=0x48556c mask=(30): code=SI_USER sent by pid=27766, uid=10853)

two signals delivered

   27766  27766 cppunittest 1733148881.022825939 RET   kill 0

kill returns


   27766  24847 cppunittest 1733148881.022837314 CALL  write(6,0x7a94769ff558,8)
   27766  27766 cppunittest 1733148881.022848647 CALL  kill(0x6c76, SIGUSR1)
   27766  24847 cppunittest 1733148881.022859939 GIO   fd 6 wrote 8 bytes
         "\^A\0\0\0\^_\0\0\0"
   27766  27766 cppunittest 1733148881.022871272 RET   kill 0
   27766  24847 cppunittest 1733148881.022882647 RET   write 8
   27766  27766 cppunittest 1733148881.022893981 PSIG  SIGUSR1 caught handler=0x48556c mask=(): code=SI_USER sent by pid=27766, uid=10853)

siguser1 sent to self?

   27766  24847 cppunittest 1733148881.022905356 CALL  setcontext(0x7a94769ff5f0)
   27766  27766 cppunittest 1733148881.022916689 CALL  write(6,0x7f7fffc945d8,8)
   27766  24847 cppunittest 1733148881.022921689 RET   setcontext JUSTRETURN



hacky patch, good enough to think about:

diff --git a/include/nutipc.hpp b/include/nutipc.hpp
index 56618d620..f6429dccd 100644
--- a/include/nutipc.hpp
+++ b/include/nutipc.hpp
@@ -607,6 +607,9 @@ void * Signal::HandlerThread<H>::main(void * comm_pipe_read_end) {

                // TBD: Die or recover on error?
                if (-1 == fdno) {
+                 if (errno == EINTR)
+                   continue;
+
                        std::stringstream e;

                        e << "Poll on communication pipe read end ";



More information about the Nut-upsdev mailing list