Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

memory safety issue: free(): invalid pointer #9

Closed
lovasoa opened this issue Mar 4, 2021 · 21 comments · Fixed by #11
Closed

memory safety issue: free(): invalid pointer #9

lovasoa opened this issue Mar 4, 2021 · 21 comments · Fixed by #11

Comments

@lovasoa
Copy link
Contributor

lovasoa commented Mar 4, 2021

Hello,
Recently a CI run in good_lp returned the following, I think this is a memory safety bug in the coin_cbc interface. I cannot reproduce the issue on my machine, but here is the CI run:

https://github.com/rust-or/good_lp/pull/2/checks

---- src/variables_macro.rs - variables (line 14) stdout ----
Test executable failed (terminated by signal).

stdout:
Dual infeasible - objective value 0
DualInfeasible objective 0 - 0 iterations time 0.002

stderr:
free(): invalid pointer

github actions runner logs.zip

good_lp uses only safe functions in coin_cbc.

@lovasoa
Copy link
Contributor Author

lovasoa commented Mar 4, 2021

The memory corruption was caused by solving the following (nonsensical, I admit) problem :

 variables!{problem:
     0 <= x;  // Create a variable x that varies between 0 and +∞
     0 <= y <= 10;  // y varies between 0 and 10
     z; // z varies between -∞ and +∞
 } // x, y, and z are now three rust variables that are in scope
 problem.minimise(x + y + z).using(default_solver).solve();

The problem is unbounded, but this still shouldn't cause a memory error.

@TeXitoi
Copy link
Collaborator

TeXitoi commented Mar 4, 2021

It looks more like a bug in coin than anything the rust binding can fix.

@lovasoa
Copy link
Contributor Author

lovasoa commented Mar 4, 2021

Were you able to reproduce the issue in coin ? I cannot reproduce it.

@TeXitoi
Copy link
Collaborator

TeXitoi commented Mar 4, 2021

I didn't try anything, but the binding doesn't allocate anything that coin must free.

@lovasoa
Copy link
Contributor Author

lovasoa commented Mar 4, 2021

Given that the issue is not deterministic, maybe the root cause is : coin-or/Cbc#223

@TeXitoi
Copy link
Collaborator

TeXitoi commented Mar 4, 2021

If you have this in tests, and you have several tests in parallel, there is chance this is the problem yes.

@lovasoa
Copy link
Contributor Author

lovasoa commented Mar 4, 2021

You may want to add a big red warning in the README and the doc of this crate, then. For a rust crate, this is a kind of serious problem.

@lovasoa
Copy link
Contributor Author

lovasoa commented Mar 4, 2021

Reading coin-or/Cbc#332 (comment) , it looks like there is a build parameter that is disabled by default called -DCBC_THRED_SAFE. Maybe this crate should statically link to a cbc compiled with this option ?

@lovasoa
Copy link
Contributor Author

lovasoa commented Mar 4, 2021

Otherwise, this crate could add a Mutex around the cbc pointer.

@dlaehnemann
Copy link
Contributor

@lovasoa Here are suggestions how to work around this (basically get a version compiled with the flag you mention), until this is fixed in a proper release -- which will probably happen with the next Cbc release:
#7 (comment)

@lovasoa
Copy link
Contributor Author

lovasoa commented Mar 4, 2021

Thanks ! But until cbc itself is thread safe, this crate should probably prevent solving multiple problems in parallel.

@TeXitoi
Copy link
Collaborator

TeXitoi commented Mar 4, 2021

I can't without a global variable, and it would block using cbc in parallel if you have a thread safe cbc.

A note about this issue can be added in the README.md and in the doc, PR welcome.

@dlaehnemann
Copy link
Contributor

Hmm, I prefer being able to run multiple instances of Cbc in parallel and will use the workaround. But this obviously requires explicitly using one of the workarounds.

And I agree that running into this repeatedly is annoying. So maybe putting this into the README somewhere prominently is a good idea, until this is fixed in Cbc.

@lovasoa
Copy link
Contributor Author

lovasoa commented Mar 4, 2021

I don't think this requires a global variable. It just requires wrapping the cbc model pointer in a mutex, doesn't it ? Maybe the crate could have a feature flag called unsafe-parallel to remove the mutex and allow parallel solving if the user has a non-standard cbc compiled with the thread safe feature flag ?

@TeXitoi
Copy link
Collaborator

TeXitoi commented Mar 4, 2021

It need a global variable, the problem is when you use several cbc model pointer.

lovasoa added a commit to lovasoa/coin_cbc that referenced this issue Mar 4, 2021
@lovasoa lovasoa mentioned this issue Mar 4, 2021
lovasoa added a commit to rust-or/good_lp that referenced this issue Mar 4, 2021
TeXitoi pushed a commit that referenced this issue Mar 4, 2021
@lovasoa
Copy link
Contributor Author

lovasoa commented Mar 4, 2021

I just tried rerunning good_lp's tests, and unfortunately this doesn't fix the problem 😢

Here is a minimal reproduction :

    #[test]
    fn unbounded() {
        // Formulate an unbounded problem and try to solve it
        let mut m = Model::default();
        let z = m.add_col();
        m.set_obj_coeff(z, 1.);
        m.set_col_lower(z, f64::NEG_INFINITY); // This causes the invalid free()
        m.set_obj_sense(Sense::Minimize);
        m.solve();
    }

I was so sure it indeed came from the concurrency bug that I didn't even try that before.

@TeXitoi
Copy link
Collaborator

TeXitoi commented Mar 4, 2021

With no parallelism? and setting it to -1e100 fixes the problem?

@lovasoa
Copy link
Contributor Author

lovasoa commented Mar 4, 2021

Yes, with a single thread. -1e100 still fails, but -1e27 works 🙁

@TeXitoi
Copy link
Collaborator

TeXitoi commented Mar 4, 2021

I can't really reproduce, but by insisting, I have segfaults. So I thing that's not enough.

lovasoa added a commit to lovasoa/coin_cbc that referenced this issue Mar 4, 2021
This was referenced Mar 4, 2021
@lovasoa
Copy link
Contributor Author

lovasoa commented Mar 4, 2021

To be clear, you never observed #9 with libcbc 2.9 ? If so, this means coin-or/Cbc#367 is a regression

@TeXitoi
Copy link
Collaborator

TeXitoi commented Mar 4, 2021

Never observed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants