bugGNU Octave - Bugs: bug #50068, Segfault, when eval_string is used...

 
 

bug #50068: Segfault, when eval_string is used in interpreter embedded mode

Submitted by:  Dmitry Messerman <mdmitry>
Submitted on:  Tue 17 Jan 2017 07:27:47 PM UTC  
 
Category: InterpreterSeverity: 3 - Normal
Priority: 5 - NormalItem Group: Segfault, Bus Error, etc.
Status: FixedAssigned to: None
Originator Name: Dmitry MessermanOpen/Closed: Closed
Release: 4.2.0Operating System: GNU/Linux

Add a New Comment(Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

(Jump to the original submission Jump to the original submission)

Sun 29 Jan 2017 02:33:16 PM UTC, comment #21:

Octave in an all-volunteer effort. Because of that, there is no guarantee that any particular bug report will be investigated, and if it is investigated, no guarantee that it will be resolved or on what kind of schedule it might get reviewed.

If you do need certainty, consider either 1) paid support such as that listed at https://www.gnu.org/software/octave/commercial-support.html, or 2) performing your own investigations since 100% of the source code is available through the Mercurial repository.

Rik <rik5>
Project Administrator
Sun 29 Jan 2017 12:33:15 PM UTC, comment #20:

Several days ago, I've posted another related bug:
https://savannah.gnu.org/bugs/?50111

However, nobody from Octave team have looked at it so far.
Please, let me know, when I should expect any kind of response.

Thanks,
Dmitry

Dmitry Messerman <mdmitry>
Fri 27 Jan 2017 07:18:26 PM UTC, comment #19:

I'll update the example, then close.

John W. Eaton <jwe>
Project Administrator
Fri 27 Jan 2017 05:22:45 PM UTC, comment #18:

Is this bug ready to be closed now? Or should there be an update to the embedded.cc example on stable so people don't attempt this?

Rik <rik5>
Project Administrator
Tue 24 Jan 2017 11:40:03 PM UTC, comment #17:

I checked in the following changeset on default

http://hg.savannah.gnu.org/hgweb/octave/rev/9f406f0b36da

I don't know if there is a fix that can be applied to stable.

Note that this deprecates both octave_main and clean_up_and_exit. I'll try to fix the docs and example.

The best thing to do is to create your own embedded_application object and let it go out of scope when you are done (or delete it if you allocated it with new).

However, I'm not sure you can reliably create another one after doing that since there are still many global objects that may expect to only be initialized once.

John W. Eaton <jwe>
Project Administrator
Sat 21 Jan 2017 10:20:11 PM UTC, comment #16:

Is there a documentation fix we can make today on the stable branch as a placeholder before any other changes? The only indication of how to use the embedded interpreter occurs in an example in Appendix A of the manual. The actual code, that is sucked in to the manual, is located in examples/code/embedded.cc. Should that be rewritten to follow jwe's code in comment #14?

Rik <rik5>
Project Administrator
Sat 21 Jan 2017 08:08:12 AM UTC, comment #15:

Thanks for proposed solution!
It works fine for me.
With regards to clean_up_and_exit: it is not essential for me.
I guess it will be fixed in one of the new versions.

Dmitry Messerman <mdmitry>
Fri 20 Jan 2017 10:17:25 PM UTC, comment #14:

We can fix the problem with the interpreter object being temporary in octave_main by making it static. But I'm not sure what to do about the new way that clean_up_and_exit works.

If you want to update your code, you could write something like this instead:

John W. Eaton <jwe>
Project Administrator
Wed 18 Jan 2017 06:04:07 PM UTC, comment #13:

One more comment.
With regards to the Rik's response.

1) Vanilla code from Appendix A does not reproduce problem, which is reported in the ticket, as feval works fine both in 4.0.2 and 4.2.0

In order to reproduce problem, which is is reported in the ticket, I'm aware of 2 ways:

- Use eval_string: example is attached in original submission
- Use source_file: if needed, I can create example of this one
as well

2) Exception thrown by cleanup_and_exit is another issue.
I've not reported it, as it has trivial workaround:
use try - catch brackets.

Dmitry Messerman <mdmitry>
Wed 18 Jan 2017 06:03:57 PM UTC, comment #12:

Oh, I was just looking at the example provided by Rik. I didn't read enough context here...

I'll try to take a look at the issue that Mike brought up about the interperter being destroyed when octave_main returns.

John W. Eaton <jwe>
Project Administrator
Wed 18 Jan 2017 06:01:14 PM UTC, comment #11:

It looks like a case of missing a catch() for the exit exception.

Until it's fixed in Octave, you should be able to work around it with something like this:

John W. Eaton <jwe>
Project Administrator
Wed 18 Jan 2017 05:55:34 PM UTC, comment #10:

Thanks for clarification!
Now I understand.
I guess that I need to wait for the next release.

Dmitry Messerman <mdmitry>
Wed 18 Jan 2017 05:48:27 PM UTC, comment #9:

> I've checked the hypothesis that octave_main does not change internal state of the process after exit.


That was not a hypothesis I put forward. What I said was that the interpreter object is initialized and then destroyed by the time octave_main returns. I did not say that that is the only thing that octave_main does. It definitely affects global state as well. Changes were made between 4.0 and 4.2 to try to encapsulate that state better into classes, and this crash appears to be a side effect that the work is still in progress.

Mike Miller <mtmiller>
Project Administrator
Wed 18 Jan 2017 05:35:05 PM UTC, comment #8:

Please note that the error you are seeing with clean_up_and_exit is not the same as the issue reported here.

The functions feval and eval_string appear to rely on different parts of the interpreter. For example, I don't think feval needs the parser to be active at all, since you are passing it a function name and an argument list, you are in effect acting as the parser.

Calling eval_string passes the text down to the parser, and that is where the crash reported here is happening.

Mike Miller <mtmiller>
Project Administrator
Wed 18 Jan 2017 04:55:41 PM UTC, comment #7:

Confirmed. This is a regression between 4.0.2 and 4.2.0. The problem is still present on the development branch (4.3.0+) as well. I'm adding jwe to the CC list since he significantly changed the exception handling mechanisms of Octave to which this appears to relate.

For a test case, I am using the vanilla code present in Appendix A, shown here for reference.

To compile, I type at a shell prompt

Also, at the shell, I have to add in the runtime libraries

Finally, I run the resulting executable and I get

It seems that clean_up_and_exit() behaves differently than it did in 4.0.2. If I eliminate the call to clean_up_and_exit and just let the interpreter go out of scope at the end of main() theni I get

Rik <rik5>
Project Administrator
Wed 18 Jan 2017 10:09:26 AM UTC, comment #6:

I've checked the hypothesis that octave_main does not change internal state of the process after exit.
According to my understanding based on the following test is doing something.

Reproduction:
1) The following code works well

#include <iostream>
#include <octave/oct.h>
#include <octave/octave.h>
#include <octave/parse.h>
#include <octave/interpreter.h>

int
main (void)
{
string_vector argv (2);
argv(0) = "embedded";
argv(1) = "-q";

octave_main (2, argv.c_str_vec (), 1);

octave_idx_type n = 2;
octave_value_list in;

for (octave_idx_type i = 0; i < n; i++)
in(i) = octave_value (5 * (i + 2));

octave_value_list out = feval ("gcd", in, 1);

if (out.length () > 0)
std::cout << "GCD of ["
<< in(0).int_value ()
<< ", "
<< in(1).int_value ()
<< "] is " << out(0).int_value ()
<< std::endl;
else
std::cout << "invalid\n";

try {
clean_up_and_exit (0);
} catch(...) {
}
}

2) The same code with line

octave_main (2, argv.c_str_vec (), 1);

commented out is crashing.

I don't understand, how above can happen if octave_main only doing the following:

1) Creates interpreter object
2) Destroys interpreter object

Dmitry Messerman <mdmitry>
Wed 18 Jan 2017 08:37:45 AM UTC, comment #5:

Thanks for quick response!
Any plans to fix this issue?

Dmitry Messerman <mdmitry>
Wed 18 Jan 2017 07:38:01 AM UTC, comment #4:

It seems that when octave_main returns, the interpreter object has been destroyed. It has gone through its command line processing and initialization of its internal state, but then it exits and cleans itself up. The subsequent call to eval_string is trying to operate on an interpreter that doesn't exist anymore. This was not the case in Octave 4.0.x, because the interpreter was not an object with contained state, it was just initializing a bunch of globals.

Mike Miller <mtmiller>
Project Administrator
Wed 18 Jan 2017 07:27:32 AM UTC, comment #3:

I agree that these examples, and my own tests, modified from the provided embedded.cc boilerplate example, succeed with Octave 4.0.x but fail on the default branch. I don't have a working 4.2 to test at the moment, but I expect it is similar to default at this point.

The segfault occurs at

Mike Miller <mtmiller>
Project Administrator
Wed 18 Jan 2017 06:58:31 AM UTC, comment #2:

Answering your questions:

1) Very similar code worked for 4.0.2
I've changed only header from toplev.h to interpreter.h
Note that on 4.2.0 version with toplev.h segfaults as well
2) There are other scenarios, where feval is not applicable.
Attached below is example of more generic case, which works
on 4.0.2 and segfaults on 4.2.0

#include <string>
#include <octave/oct.h>
#include <octave/octave.h>
#include <octave/parse.h>
#include <octave/toplev.h>

int main (int argc, char** argv) {
string_vector octave_argv (2);
octave_argv(0) = "embedded";
octave_argv(1) = "-q";
octave_main (2, octave_argv.c_str_vec (), 1);
int parse_status;
eval_string(std::string("[2,1;1,2]\\[1;1]"),0, parse_status);
std::_Exit(0);
return 0;
}

Expected output from 4.0.2:

ans =

0.333333333333333
0.333333333333333

Current output from 4.2.0:

Segmentation fault

Dmitry Messerman <mdmitry>
Wed 18 Jan 2017 04:59:35 AM UTC, comment #1:

Has this code worked with any version of Octave? Why not use feval if you want to evaluate a function as shown in Appendix A of the Octave manual?

Rik <rik5>
Project Administrator
Tue 17 Jan 2017 07:27:47 PM UTC, original submission:

The following code segfaults:

#include <string>
#include <octave/oct.h>
#include <octave/octave.h>
#include <octave/parse.h>
#include <octave/interpreter.h>

int main (int argc, char** argv) {
string_vector octave_argv (2);
octave_argv(0) = "embedded";
octave_argv(1) = "-q";
octave_main (2, octave_argv.c_str_vec (), 1);
int parse_status;
eval_string(std::string("who"),0, parse_status);
return 0;
}

Dmitry Messerman <mdmitry>

 

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

Attach File(s):
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -unavailable- added by jwe (Posted a comment)
  • -unavailable- added by rik5
  • -unavailable- added by mtmiller (Posted a comment)
  • -unavailable- added by rik5 (Posted a comment)
  • -unavailable- added by mdmitry (Submitted the item)
  •  

    Do you think this task is very important?
    If so, you can click here to add your encouragement to it.
    This task has 0 encouragements so far.

    Only project members can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

     

     

    Follow 5 latest changes.

    Date Changed By Updated Field Previous Value => Replaced By
    Mon 13 Mar 2017 05:16:15 AM UTCrik5StatusConfirmed=>Fixed
      Open/ClosedOpen=>Closed
    Wed 18 Jan 2017 04:55:41 PM UTCrik5StatusNeed Info=>Confirmed
      Carbon-Copy-=>Added jwe
    Wed 18 Jan 2017 04:59:35 AM UTCrik5StatusNone=>Need Info

    Back to the top


    Powered by Savane 3.1-cleanup1