[Cbc] Segfault / memory corruption after "assignSolver" in "CbcModel"

Dirk Eßer essdir at web.de
Fri May 9 06:00:06 EDT 2014


Hi John,

thanks for the reply. I now have a minimal example (for some definition 
of minimal, which you can find attached), with which I can reproduce the 
access violation. Right now, it seems, that I have the choice between

  * getting a segfault when trying to clean-up all solvers instanciated
    during the program run, or
  * leaking a solver instance.

I am not quite comfortable with option 2, since I don't know, how much 
memory is actually leaked in this case, in particular as the actual 
application will solve quite a few MIPs sequentially in the same 
process. If it were only a couple of bytes per solver instance, then I 
am almost willing accept that as "price to pay" for the preprocessing 
step. But I don't know the inner workings of the solvers involved enough 
to make a judgement here.

Also, I am still not convinced, that the error isn't entirely in our own 
code; right now, though, I don't see anything inherently wrong. Any help 
appreciated.


Cheers,
Dirk Eßer



Am 07.05.2014 19:36, schrieb John Forrest:
> Dirk,
>
> The -cpp was a nice idea - but impossible to keep current - so 
> something may be broken.
>
> Try using code from the Cbc/examples driver3.cpp or driver4.cpp which 
> should give you the same flexibility.
>
> John Forrest
> On 07/05/14 11:18, Dirk Eßer wrote:
>> Hello,
>>
>> I have a little problem adding a preprocessing step to program doing 
>> MIP solving using the CBC library. The problem is, that the program 
>> fails with more or less random memory corruption (and in the better 
>> cases: with a segfault) some of the time.
>>
>> The CbcModel instance is created programmatically
>>
>>     OsiClpSolverInterface iface;
>>     CoinPackedMatrix pmx(false, num_columns, num_rows, num_elements,
>>     matrix, columns, starts, lengths);
>>
>>     iface.setObjSense(-1.0);
>>     iface.loadProblem(pmx, 0, 0, objective, senses, rights, 0);
>>     iface.passInMessageHandler(&printer);
>>
>>     model_ptr LP(new CbcModel(iface));
>>     ... adding stuff via LP->addObjects(...) to declare integer
>>     constraints on variables and a few SOSes ...
>>
>> Things work fine, if we directly compute a solution without further 
>> preprocessing via
>>
>>     LP->initialSolve();
>>     LP->branchAndBound();
>>
>> We now try to add a pre-processing step to the solution process. As a 
>> starting point, we used the driver code generated by the CBC command 
>> line tool ("-cpp 0", which doesn't compile).
>>
>>     OsiSolverInterface* original_solver = LP->solver();
>>     OsiSolverInterface* cloned_solver = original_solver->clone();
>>     OsiSolverInterface* configured_solver = 0;
>>
>>     cloned_solver->passInMessageHandler(LP->messageHandler());
>>     cloned_solver->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo);
>>
>>     CglPreProcess processor;
>>
>>                 {
>>                     CglProbing prober;
>>                     prober.setUsingObjective(1);
>>                     prober.setMaxPass(3);
>>     prober.setMaxProbeRoot(cloned_solver->getNumCols());
>>                     prober.setMaxElements(100);
>>                     prober.setMaxLookRoot(50);
>>                     prober.setRowCuts(3);
>>                     processor.addCutGenerator(&prober);
>>                 }
>>
>>     configured_solver =
>>     processor.preProcessNonDefault(*cloned_solver, 2, 10);
>>
>>     cloned_solver->setHintParam(OsiDoInBranchAndCut, false, OsiHintDo);
>>
>>     if (!configured_solver)
>>     {
>>         delete cloned_solver;
>>         return status::infeasible;
>>     }
>>
>>     configured_solver->setHintParam(OsiDoInBranchAndCut, false,
>>     OsiHintDo);
>>
>>     OsiSolverInterface* configured_clone = configured_solver->clone();
>>
>>     LP->assignSolver(configured_clone, true /* Kill previous solver
>>     */); /*-- XXX --*/
>>     LP->initialSolve();
>>     LP->branchAndBound();
>>
>>     int n_cols = cloned_solver->getNumCols();
>>     processor.postProcess(*LP->solver());
>>
>>     LP->assignSolver(cloned_solver, true /* Kill previous solver */);
>>     memcpy(LP->bestSolution(), LP->solver()->getColSolution(), n_cols
>>     * sizeof(double));
>>
>> It seems, that we are violating one or two unwritten laws of memory 
>> management with CBC, but I am at loss as what we are doing wrong 
>> here. Any help, hints, pointer to documentation, etc. is highly 
>> appreciated.
>>
>> Cheers,
>> Dirk Eßer
>>
>>
>> _______________________________________________
>> Cbc mailing list
>> Cbc at list.coin-or.org
>> http://list.coin-or.org/mailman/listinfo/cbc
>
>
>
> _______________________________________________
> Cbc mailing list
> Cbc at list.coin-or.org
> http://list.coin-or.org/mailman/listinfo/cbc

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://list.coin-or.org/pipermail/cbc/attachments/20140509/1a5b54dd/attachment.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: user_driver.cpp
Type: text/x-c++src
Size: 11175 bytes
Desc: not available
URL: <http://list.coin-or.org/pipermail/cbc/attachments/20140509/1a5b54dd/attachment.bin>


More information about the Cbc mailing list