Re: segfaults building documentation when machine under load

Daniel J Sebald <[email protected]>
Newsgroups gmane.comp.gnu.octave.maintainers
Message-ID <[email protected]>
On 5/19/20 9:54 PM, John W. Eaton wrote:
> On 5/19/20 4:11 PM, Dmitri A. Sergatskov wrote:
>>
>>
>> On Tue, May 19, 2020 at 4:02 PM John W. Eaton <[email protected] 
>> <mailto:[email protected]>> wrote:
>>
>>     On 5/19/20 3:26 PM, Dmitri A. Sergatskov wrote:
>>
>>      >     Should we switch to bug-tracker?
>>      >     I was able to get a crash when I bumped the jobs to 200.
>>      >     bt is attached. The relevant part seems to be:
>>
>>     If I use a large number of jobs, I see
>>
>>         error: imwrite: invalid empty image
>>         error: called from
>>             __imwrite__ at line 40 column 5
>>             imwrite at line 125 column 5
>>             print at line 755 column 13
>>             interpimages at line 72 column 5
>>
>>     but no segfaults.
>>
>>     It does look like a threading issue.
>>
>>
>> I used a simplified test by Andreas:
>>
>> parallel -N0 -q octave --norc --silent --no-history --eval 'figure 
>> (1,"visible", "off");' ::: {1..200}
> 
> OK, I'm able to duplicate the problem using this method.
> 
> In the stack traces I've seen, Octave is crashing inside the interpreter 
> object destructor while attempting to close any remaining figures.
> 
> Changing the eval above to be
> 
>    figure (1, "visible", "off"); close ("all"); pause (1);
> 
> eliminates the crash for me, apparently because then there are no figure 
> windows to close when exiting.  But attempting the same thing in the 
> doc/interpreter scripts that generate plots I see the "invalid empty 
> image" error on every attempt to create a figure, at least when using a 
> large number of parallel Make jobs.
> 
> So clearly this kind of change is not a solution, but it may point us 
> toward one.  Ultimately, we need to determine the correct sequence for 
> shutting down the GUI and interpreter, including what actions can happen 
> or need to be blocked, and what signals need to be sent or locks 
> acquired so that there are no more races between the threads.
> 
> It's a bit tricky because figures can have callbacks set to run when the 
> figure is closed.  Do we expect those to run when Octave is in the 
> process of exiting or is it OK to skip them?  Those functions could 
> register code to run when Octave exits.  Should that be possible?  Would 
> it be OK for an atexit function to display a graph?  What is reasonable 
> to expect or attempt to do?

Are a "close" command and upper-right close button the same path, 
essentially?  So it is

1) "close"
2) call close callback
3) destroy figure object

?  What is the route when Octave exits?  Also, is the graphics engine 
still valid in the exit scenario?  At the end of

void
gh_manager::execute_callback (const graphics_handle& h,
                               const octave_value& cb_arg,
                               const octave_value& data)
{

is the following:

       // Redraw after interacting with a user-interface (ui*) object.
       if (Vdrawnow_requested)
         {
           if (go)
             {
               std::string go_name
                 = go.get_properties ().graphics_object_name ();

               if (go_name.length () > 1
                   && go_name[0] == 'u' && go_name[1] == 'i')
                 {
                   Fdrawnow (m_interpreter);
                   Vdrawnow_requested = false;
                 }
             }
         }

Perhaps Fdrawnow() is where the failure is happening because the 
graphics was shut down prior.  To debug, place a

printf("About to redraw...")
                   Fdrawnow (m_interpreter);
printf("...finished redraw")

and retry the doc build.

Dan
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.