bugGNU Octave - Bugs: bug #52084, pause() fails after an async...

 
 

bug #52084: pause() fails after an async system call

Submitter:  None
Submitted:  Fri 22 Sep 2017 02:17:09 AM UTC
   
 
Category:  Octave Function Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Inaccurate Result
Status:  Fixed Assigned to:  None
Originator Name:  Alex Barnett Originator Email:  -email is unavailable-
Open/Closed:  * Closed Release:  * 4.0.0
Operating System:  * GNU/Linux Fixed Release:  None
Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Fri 22 Sep 2017 11:04:26 PM UTC, comment #6: 
Mike Miller <mtmiller>
Group Member
Fri 22 Sep 2017 06:56:03 AM UTC, comment #5: 

Works here.  Nice.

Dan Sebald <sebald>
Fri 22 Sep 2017 06:28:32 AM UTC, comment #4: 

Please try the attached patch, it works for me to solve this bug.

(file #41868)

Mike Miller <mtmiller>
Group Member
Fri 22 Sep 2017 06:06:12 AM UTC, comment #3: 

OK, since you have a better understanding of the SIGCHLD, I'll let you think that one over.  It might not be that the child process is exiting, but that it is the shell simply signaling that it's command is complete.  I'll continue the discussion in the thread you referenced, https://savannah.gnu.org/bugs/?37591

Dan Sebald <sebald>
Fri 22 Sep 2017 06:00:06 AM UTC, comment #2: 

See bug #37591 for the problem of Octave not reaping child processes with system(..."async").

I suspect this is as simple as the nanosleep function is being interrupted by the SIGCHLD that is sent when a child process exits. There needs to be some logic in place if nanosleep returns early and still has some sleeping to do, if the signal is safe to ignore, the caller should call nanosleep again with the time remaining.

Mike Miller <mtmiller>
Group Member
Fri 22 Sep 2017 04:20:57 AM UTC, comment #1: 

** There's a zombie-like process bug which I will point out at the end of this post.

Interesting find.  A little simpler way of illustrating is to do


system('ls',0,'async');
% Carriage return
pause(1);


as individual lines and as selecting the two and pasting--or use a function as follows:


function myfunc1()
  system('ls',0,'async');
  pause(1);
end
% No pause
myfunc1();


versus


function myfunc()
  system('ls');
  pause(1);
end
% Pause
myfunc2();


Perhaps this isn't as strange as it first appears.  The two routines, system() and pause(), both ultimately go back to system functions.

system() with the 'async' option calls this functin:

pid_t
octave_async_system_wrapper (const char *cmd)
{
  int retval = -1;

  if (! cmd)
    return retval;

#if defined (OCTAVE_USE_WINDOWS_API)

  STARTUPINFO si;
  PROCESS_INFORMATION pi;

  ZeroMemory (&si, sizeof (si));
  ZeroMemory (&pi, sizeof (pi));

  char *xcmd = (char *) malloc (strlen (cmd) + 1);

  strcpy (xcmd, cmd);

  if (! CreateProcess (0, xcmd, 0, 0, FALSE, 0, 0, 0, &si, &pi))
    retval = -1;
  else
    {
      retval = pi.dwProcessId;

      CloseHandle (pi.hProcess);
      CloseHandle (pi.hThread);
    }

  free (xcmd);

#else

  pid_t pid = fork ();

  if (pid == 0)
    execl (SHELL_PATH, "sh", "-c", cmd, (char *) (0));
  else
    retval = pid;

#endif

  return retval;
}


pause() calls this function:

int
octave_nanosleep_wrapper (const struct timespec *requested,
                          struct timespec *remaining)
{
  return nanosleep (requested, remaining);
}


where nanosleep() is in <time.h>.

There are a couple plausible routes of investigations.  I'm imagining somehow the end of the asynchronous process is triggering an end to the nanosleep.  Is there something that is being sent back to Octave when the system() command completes that would wake the Octave process from sleep?  Doesn't seem like it because the async system route forks a process to do the system command, and the execl() command would only know the forked process ID not the original Octave process ID.  Is it possible that the pause() is getting placed in the forked process rather than in the Octave process?

Looking at the octave_async_system_wrapper() construct after the fork, something seems strange.  There is a "retval = pid" in the case of the original Octave process, i.e., pid != 0.  In the case of the forked process (pid = 0), there is a return value of -1 sent back.  But where that is going to, I don't know, because the calling function just returns the return value of octave_async_system_wrapper().  It seems to me that the forked process should execute the system command and then simply quit. 
Otherwise, it's a zombie process.  Call


myfunc1()
myfunc1()
myfunc1()
...
myfunc1()


twenty or thirty times then look at the list of system processes and one will see a list of twenty "sh" processes.  Well, technically they aren't zombie processes because if I exit Octave, all the "sh" processes terminate along with it rather than hanging around.  But still, I'm wondering if something should be fixed there as well.

Dan Sebald <sebald>
Fri 22 Sep 2017 02:17:09 AM UTC, original submission:  

This is a weird one, but the first pause after an asynchronous system call is ignored. Other system calls are fine.
Simple example:

disp('should pause 1 sec each time...')
pause(1)   % is done
system('ls'); 1
pause(1)   % is done
system('ls',0,'async'); 2
pause(1)   % this one skipped
pause(1)   % this one is done
system('ls'); 3
pause(1)   % is done
disp('done')

Takes 4 sec rather than the desired 5.

Anonymous

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

Attached Files
file #41868:  bug52084.patch added by mtmiller (999B - text/x-patch)

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by mtmiller (Posted a comment)
  • -email is unavailable- added by sebald (Posted a comment)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 5 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2017-09-22 mtmiller StatusPatch Submitted Fixed
        Open/ClosedOpen Closed
    2017-09-22 mtmiller Attached File- Added bug52084.patch, #41868
        StatusConfirmed Patch Submitted
    2017-09-22 mtmiller StatusNone Confirmed

    Back to the top

    Powered by Savane 3.13-02a9.
    Corresponding source code