[gringo] 02/05: add patch to fix random python segfaults
Thomas Krennwallner
tkren-guest at moszumanska.debian.org
Sun May 1 07:01:21 UTC 2016
This is an automated email from the git hooks/post-receive script.
tkren-guest pushed a commit to branch devel
in repository gringo.
commit b9a88e4ebfa55c99dde5dd379fc886c4aff8278e
Author: Thomas Krennwallner <tkren at kr.tuwien.ac.at>
Date: Sun May 1 07:37:00 2016 +0200
add patch to fix random python segfaults
gringo-solve-multi.patch fixes random multithreading segfaults with the
python module.
Upstream bug 117: https://sourceforge.net/p/potassco/bugs/117/
---
debian/patches/gringo-solve-multi.patch | 350 ++++++++++++++++++++++++++++++++
debian/patches/series | 1 +
2 files changed, 351 insertions(+)
diff --git a/debian/patches/gringo-solve-multi.patch b/debian/patches/gringo-solve-multi.patch
new file mode 100644
index 0000000..248c871
--- /dev/null
+++ b/debian/patches/gringo-solve-multi.patch
@@ -0,0 +1,350 @@
+Author: Roland Kaminski <kaminski at cs.uni-potsdam.de>
+Description: fixes random multithreading segfaults with the python module
+Bug: https://sourceforge.net/p/potassco/bugs/117/
+Index: gringo-git-gbp/libgringo/gringo/control.hh
+===================================================================
+--- gringo-git-gbp.orig/libgringo/gringo/control.hh
++++ gringo-git-gbp/libgringo/gringo/control.hh
+@@ -173,9 +173,10 @@ struct Control {
+ virtual DomainProxy &getDomain() = 0;
+
+ virtual void ground(GroundVec const &vec, Any &&context) = 0;
+- virtual SolveResult solve(ModelHandler h, Assumptions &&assumptions) = 0;
+- virtual SolveFuture *solveAsync(ModelHandler mh, FinishHandler fh, Assumptions &&assumptions) = 0;
+- virtual SolveIter *solveIter(Assumptions &&assumptions) = 0;
++ virtual void prepareSolve(Assumptions &&assumptions) = 0;
++ virtual SolveResult solve(ModelHandler h) = 0;
++ virtual SolveFuture *solveAsync(ModelHandler mh, FinishHandler fh) = 0;
++ virtual SolveIter *solveIter() = 0;
+ virtual void add(std::string const &name, FWStringVec const ¶ms, std::string const &part) = 0;
+ virtual void load(std::string const &filename) = 0;
+ virtual Value getConst(std::string const &name) = 0;
+Index: gringo-git-gbp/libgringo/src/lua.cc
+===================================================================
+--- gringo-git-gbp.orig/libgringo/src/lua.cc
++++ gringo-git-gbp/libgringo/src/lua.cc
+@@ -1046,6 +1046,7 @@ struct ControlWrap {
+ mIndex = lua_gettop(L);
+ }
+ Control::Assumptions *ass = getAssumptions(L, assIdx);
++ protect<void>(L, [&ctl, ass]() { ctl.prepareSolve(std::move(*ass)); });
+ lua_pushinteger(L, protect<int>(L, [L, &ctl, model, ass, mhIndex, mIndex]() {
+ return (int)ctl.solve(!model ? Control::ModelHandler(nullptr) : [L, model, mhIndex, mIndex](Gringo::Model const &m) -> bool {
+ LuaClear lc(L);
+@@ -1057,7 +1058,7 @@ struct ControlWrap {
+ Location loc("<on_model>", 1, 1, "<on_model>", 1, 1);
+ handleError(L, loc, code, "error in model callback");
+ return lua_type(L, -1) == LUA_TNIL || lua_toboolean(L, -1);
+- }, std::move(*ass));
++ });
+ }));
+ return 1;
+ }
+@@ -1075,6 +1076,7 @@ struct ControlWrap {
+ int mhIndex = !lua_isnone(L, 3) && !lua_isnil(L, 3) ? 3 : 0;
+ int fhIndex = !lua_isnone(L, 4) && !lua_isnil(L, 4) ? 4 : 0;
+ Control::Assumptions *ass = getAssumptions(L, assIdx);
++ protect<void>(L, [&ctl, ass]() { ctl.prepareSolve(std::move(*ass)); });
+ auto &future = *(Gringo::SolveFuture **)lua_newuserdata(L, sizeof(Gringo::SolveFuture*));
+ lua_State *M = nullptr;
+ if (mhIndex || fhIndex) {
+@@ -1097,7 +1099,7 @@ struct ControlWrap {
+ lua_xmove(L, M, 1);
+ fhIndex = lua_gettop(M);
+ }
+- future = protect<Gringo::SolveFuture*>(L, [&ctl, model, mhIndex, fhIndex, ass, M]() {
++ future = protect<Gringo::SolveFuture*>(L, [&ctl, model, mhIndex, fhIndex, M]() {
+ auto mh = !mhIndex ? Control::ModelHandler(nullptr) : [M, mhIndex, model](Gringo::Model const &m) -> bool {
+ LuaClear lc(M);
+ lua_pushcfunction(M, luaTraceback);
+@@ -1119,7 +1121,7 @@ struct ControlWrap {
+ Location loc("<on_finish>", 1, 1, "<on_finish>", 1, 1);
+ handleError(M, loc, code, "error in model callback");
+ };
+- return ctl.solveAsync(mh, fh, std::move(*ass));
++ return ctl.solveAsync(mh, fh);
+ });
+ luaL_getmetatable(L, "gringo.SolveFuture");
+ lua_setmetatable(L, -2);
+@@ -1131,8 +1133,9 @@ struct ControlWrap {
+ lua_unsetuservaluefield(L, 1, "stats");
+ int assIdx = !lua_isnone(L, 2) && !lua_isnil(L, 2) ? 2 : 0;
+ Control::Assumptions *ass = getAssumptions(L, assIdx);
++ protect<void>(L, [&ctl, ass]() { ctl.prepareSolve(std::move(*ass)); });
+ auto &iter = *(Gringo::SolveIter **)lua_newuserdata(L, sizeof(Gringo::SolveIter*));
+- iter = protect<Gringo::SolveIter*>(L, [&ctl, ass]() { return ctl.solveIter(std::move(*ass)); });
++ iter = protect<Gringo::SolveIter*>(L, [&ctl]() { return ctl.solveIter(); });
+ luaL_getmetatable(L, "gringo.SolveIter");
+ lua_setmetatable(L, -2);
+ return 1;
+Index: gringo-git-gbp/libgringo/src/python.cc
+===================================================================
+--- gringo-git-gbp.orig/libgringo/src/python.cc
++++ gringo-git-gbp/libgringo/src/python.cc
+@@ -2069,11 +2069,12 @@ struct ControlWrap {
+ Gringo::SolveFuture *future;
+ Object omh(mh, true);
+ Object ofh(fh, true);
+- if (!protect([self, omh, ofh, &future, &ass]() {
++ if (!protect([self, &ass]() { self->ctl->prepareSolve(std::move(ass)); })) { return nullptr; }
++ if (!protect([self, omh, ofh, &future]() {
++ PyUnblock unblock;
+ future = (self->ctl->solveAsync(
+ omh == Py_None ? Control::ModelHandler(nullptr) : [omh](Gringo::Model const &m) -> bool { PyBlock b; (void)b; return on_model(m, omh); },
+- ofh == Py_None ? Control::FinishHandler(nullptr) : [ofh](Gringo::SolveResult ret, bool canceled) -> void { PyBlock b; (void)b; on_finish(ret, canceled, ofh); },
+- std::move(ass)
++ ofh == Py_None ? Control::FinishHandler(nullptr) : [ofh](Gringo::SolveResult ret, bool canceled) -> void { PyBlock b; (void)b; on_finish(ret, canceled, ofh); }
+ ));
+ })) { return nullptr; }
+ PyObject *ret = SolveFuture::new_(*future);
+@@ -2088,8 +2089,12 @@ struct ControlWrap {
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", const_cast<char **>(kwlist), &pyAss)) { return nullptr; }
+ Gringo::Control::Assumptions ass;
+ if (!getAssumptions(pyAss, ass)) { return nullptr; }
++ if (!protect([self, &ass]() { self->ctl->prepareSolve(std::move(ass)); })) { return nullptr; }
+ Gringo::SolveIter *iter;
+- if (!protect([self, &iter, &ass]() { iter = (self->ctl->solveIter(std::move(ass))); })) { return nullptr; }
++ if (!protect([self, &iter]() {
++ PyUnblock unblock;
++ iter = self->ctl->solveIter();
++ })) { return nullptr; }
+ PyObject *ret = SolveIter::new_(*iter);
+ return ret;
+ }
+@@ -2104,11 +2109,11 @@ struct ControlWrap {
+ Gringo::SolveResult ret;
+ Gringo::Control::Assumptions ass;
+ if (!getAssumptions(pyAss, ass)) { return nullptr; }
+- if (!protect([self, mh, &ret, &ass]() {
++ if (!protect([self, &ass]() { self->ctl->prepareSolve(std::move(ass)); })) { return nullptr; }
++ if (!protect([self, mh, &ret]() {
+ PyUnblock unblock;
+ ret = (self->ctl->solve(
+- mh == Py_None ? Control::ModelHandler(nullptr) : [mh](Gringo::Model const &m) { PyBlock block; return on_model(m, Object(mh, true)); },
+- std::move(ass)
++ mh == Py_None ? Control::ModelHandler(nullptr) : [mh](Gringo::Model const &m) { PyBlock block; return on_model(m, Object(mh, true)); }
+ ));
+ })) { return nullptr; }
+ return SolveResult::get(ret);
+Index: gringo-git-gbp/app/example/main.cc
+===================================================================
+--- gringo-git-gbp.orig/app/example/main.cc
++++ gringo-git-gbp/app/example/main.cc
+@@ -24,16 +24,18 @@
+ void example1() {
+ std::vector<char const *> args{"clingo", "-e", "brave", nullptr};
+ DefaultGringoModule module;
+- ClingoLib lib(module, args.size() - 2, args.data());
++ Gringo::Scripts scripts(module);
++ ClingoLib lib(scripts, args.size() - 2, args.data());
+ lib.add("base", {}, "a :- not b. b :- not a.");
+ lib.ground({{"base", {}}}, nullptr);
++ lib.prepareSolve({});
+ lib.solve([](Gringo::Model const &m) {
+ for (auto &atom : m.atoms(Gringo::Model::SHOWN)) {
+ std::cout << atom << " ";
+ }
+ std::cout << std::endl;
+ return true;
+- }, {});
++ });
+ }
+
+ int main() {
+Index: gringo-git-gbp/app/gringo/main.cc
+===================================================================
+--- gringo-git-gbp.orig/app/gringo/main.cc
++++ gringo-git-gbp/app/gringo/main.cc
+@@ -168,8 +168,10 @@ struct IncrementalControl : Gringo::Cont
+ }
+ virtual void onModel(Gringo::Model const &) { }
+ virtual bool blocked() { return false; }
+- virtual Gringo::SolveResult solve(ModelHandler, Assumptions &&ass) {
++ virtual void prepareSolve(Assumptions &&ass) {
+ if (!ass.empty()) { std::cerr << "warning: the lparse format does not support assumptions" << std::endl; }
++ }
++ virtual Gringo::SolveResult solve(ModelHandler) {
+ if (!grounded) {
+ if (incremental) { out.incremental(); }
+ }
+@@ -177,10 +179,10 @@ struct IncrementalControl : Gringo::Cont
+ out.finish();
+ return Gringo::SolveResult::UNKNOWN;
+ }
+- virtual Gringo::SolveIter *solveIter(Assumptions &&) {
++ virtual Gringo::SolveIter *solveIter() {
+ throw std::runtime_error("solving not supported in gringo");
+ }
+- virtual Gringo::SolveFuture *solveAsync(ModelHandler, FinishHandler, Assumptions &&) { throw std::runtime_error("solving not supported in gringo"); }
++ virtual Gringo::SolveFuture *solveAsync(ModelHandler, FinishHandler) { throw std::runtime_error("solving not supported in gringo"); }
+ virtual Gringo::Statistics *getStats() { throw std::runtime_error("statistics not supported in gringo (yet)"); }
+ virtual void assignExternal(Gringo::Value ext, Gringo::TruthValue val) {
+ Gringo::PredicateDomain::element_type *atm = out.find2(ext);
+@@ -323,7 +325,8 @@ protected:
+ Gringo::Control::GroundVec parts;
+ parts.emplace_back("base", FWValVec{});
+ inc.ground(parts, Gringo::Any());
+- inc.solve(nullptr, {});
++ inc.prepareSolve({});
++ inc.solve(nullptr);
+ }
+ }
+
+Index: gringo-git-gbp/libclingo/src/clingocontrol.cc
+===================================================================
+--- gringo-git-gbp.orig/libclingo/src/clingocontrol.cc
++++ gringo-git-gbp/libclingo/src/clingocontrol.cc
+@@ -203,7 +203,8 @@ void ClingoControl::main() {
+ Gringo::Control::GroundVec parts;
+ parts.emplace_back("base", Gringo::FWValVec{});
+ ground(parts, Gringo::Any());
+- solve(nullptr, {});
++ prepareSolve({});
++ solve(nullptr);
+ }
+ }
+ bool ClingoControl::onModel(Clasp::Model const &m) {
+@@ -284,11 +285,18 @@ unsigned ClingoControl::getRootKey() {
+ Gringo::ConfigProxy &ClingoControl::getConf() {
+ return *this;
+ }
+-Gringo::SolveIter *ClingoControl::solveIter(Assumptions &&ass) {
++void ClingoControl::prepareSolve(Assumptions &&ass) {
++ if (!grounded) {
++ if (incremental) { out->incremental(); }
++ }
++ grounded = false;
++ if (update()) { out->finish(); }
++ ass_ = toLparseAssumptions(std::move(ass));
++}
++Gringo::SolveIter *ClingoControl::solveIter() {
+ if (!clingoMode_) { throw std::runtime_error("solveIter is not supported in gringo gringo mode"); }
+ #if WITH_THREADS
+ prepare_(nullptr, nullptr);
+- clasp->assume(toClaspAssumptions(std::move(ass)));
+ solveIter_ = Gringo::gringo_make_unique<ClingoSolveIter>(clasp->startSolveAsync(), static_cast<Clasp::Asp::LogicProgram&>(*clasp->program()), *out, clasp->ctx);
+ return solveIter_.get();
+ #else
+@@ -296,11 +304,10 @@ Gringo::SolveIter *ClingoControl::solveI
+ throw std::runtime_error("solveIter requires clingo to be build with thread support");
+ #endif
+ }
+-Gringo::SolveFuture *ClingoControl::solveAsync(ModelHandler mh, FinishHandler fh, Assumptions &&ass) {
++Gringo::SolveFuture *ClingoControl::solveAsync(ModelHandler mh, FinishHandler fh) {
+ if (!clingoMode_) { throw std::runtime_error("solveAsync is not supported in gringo gringo mode"); }
+ #if WITH_THREADS
+ prepare_(mh, fh);
+- clasp->assume(toClaspAssumptions(std::move(ass)));
+ solveFuture_ = Gringo::gringo_make_unique<ClingoSolveFuture>(clasp->solveAsync(nullptr));
+ return solveFuture_.get();
+ #else
+@@ -314,11 +321,6 @@ bool ClingoControl::blocked() {
+ return clasp->solving();
+ }
+ void ClingoControl::prepare_(Gringo::Control::ModelHandler mh, Gringo::Control::FinishHandler fh) {
+- if (!grounded) {
+- if (incremental) { out->incremental(); }
+- }
+- grounded = false;
+- if (update()) { out->finish(); }
+ if (clingoMode_) {
+ #if WITH_THREADS
+ solveIter_ = nullptr;
+@@ -331,35 +333,45 @@ void ClingoControl::prepare_(Gringo::Con
+ if (pgf_) { pgf_(*prg); }
+ clasp->prepare(enableEnumAssupmption_ ? Clasp::ClaspFacade::enum_volatile : Clasp::ClaspFacade::enum_static);
+ if (psf_) { psf_(*clasp);}
++ clasp->assume(toClaspAssumptions(std::move(ass_)));
+ }
+ }
+
+-Clasp::LitVec ClingoControl::toClaspAssumptions(Gringo::Control::Assumptions &&ass) const {
+- Clasp::LitVec outAss;
++std::vector<int> ClingoControl::toLparseAssumptions(Gringo::Control::Assumptions &&ass) const {
++ std::vector<int> outAss;
+ if (!clingoMode_ || !clasp->program()) { return outAss; }
+- const Clasp::Asp::LogicProgram* prg = static_cast<const Clasp::Asp::LogicProgram*>(clasp->program());
+ for (auto &x : ass) {
+ auto atm = out->find2(x.first);
+ if (atm && atm->second.hasUid()) {
+- Clasp::Literal lit = prg->getLiteral(atm->second.uid());
+- outAss.push_back(x.second ? lit : ~lit);
++ int uid = atm->second.uid();
++ outAss.push_back(x.second ? uid : -uid);
+ }
+ else if (x.second) {
+- Clasp::Literal lit = prg->getLiteral(1);
+- outAss.push_back(lit);
++ outAss.push_back(1);
+ break;
+ }
+ }
+ return outAss;
++
++}
++Clasp::LitVec ClingoControl::toClaspAssumptions(std::vector<int> &&ass) const {
++ Clasp::LitVec outAss;
++ const Clasp::Asp::LogicProgram* prg = static_cast<const Clasp::Asp::LogicProgram*>(clasp->program());
++ for (auto &x : ass) {
++ Clasp::Literal lit = prg->getLiteral(std::abs(x));
++ outAss.push_back(x > 0 ? lit : ~lit);
++ }
++ ass.clear();
++ return outAss;
+ }
+
+-Gringo::SolveResult ClingoControl::solve(ModelHandler h, Assumptions &&ass) {
++Gringo::SolveResult ClingoControl::solve(ModelHandler h) {
+ prepare_(h, nullptr);
+- clasp->assume(toClaspAssumptions(std::move(ass)));
+ return clingoMode_ ? convert(clasp->solve(nullptr)) : Gringo::SolveResult::UNKNOWN;
+ }
+
+ void ClingoControl::cleanupDomains() {
++ prepareSolve({});
+ prepare_(nullptr, nullptr);
+ if (clingoMode_) {
+ Clasp::Asp::LogicProgram &prg = static_cast<Clasp::Asp::LogicProgram&>(*clasp->program());
+Index: gringo-git-gbp/libclingo/clingo/clingocontrol.hh
+===================================================================
+--- gringo-git-gbp.orig/libclingo/clingo/clingocontrol.hh
++++ gringo-git-gbp/libclingo/clingo/clingocontrol.hh
+@@ -230,7 +230,8 @@ public:
+ void onFinish(Clasp::ClaspFacade::Result ret);
+ bool update();
+
+- Clasp::LitVec toClaspAssumptions(Gringo::Control::Assumptions &&ass) const;
++ Clasp::LitVec toClaspAssumptions(std::vector<int> &&ass) const;
++ std::vector<int> toLparseAssumptions(Gringo::Control::Assumptions &&ass) const;
+
+ // {{{2 DomainProxy interface
+
+@@ -257,7 +258,8 @@ public:
+ virtual void ground(Gringo::Control::GroundVec const &vec, Gringo::Any &&context);
+ virtual void add(std::string const &name, Gringo::FWStringVec const ¶ms, std::string const &part);
+ virtual void load(std::string const &filename);
+- virtual Gringo::SolveResult solve(ModelHandler h, Assumptions &&ass);
++ virtual void prepareSolve(Assumptions &&ass);
++ virtual Gringo::SolveResult solve(ModelHandler h);
+ virtual bool blocked();
+ virtual std::string str();
+ virtual void assignExternal(Gringo::Value ext, Gringo::TruthValue);
+@@ -267,8 +269,8 @@ public:
+ virtual void useEnumAssumption(bool enable);
+ virtual bool useEnumAssumption();
+ virtual void cleanupDomains();
+- virtual Gringo::SolveIter *solveIter(Assumptions &&ass);
+- virtual Gringo::SolveFuture *solveAsync(ModelHandler mh, FinishHandler fh, Assumptions &&ass);
++ virtual Gringo::SolveIter *solveIter();
++ virtual Gringo::SolveFuture *solveAsync(ModelHandler mh, FinishHandler fh);
+
+ // }}}2
+
+@@ -286,6 +288,7 @@ public:
+ Clasp::Cli::ClaspCliConfig &claspConfig_;
+ PostGroundFunc pgf_;
+ PreSolveFunc psf_;
++ std::vector<int> ass_;
+ #if WITH_THREADS
+ std::unique_ptr<ClingoSolveFuture> solveFuture_;
+ std::unique_ptr<ClingoSolveIter> solveIter_;
diff --git a/debian/patches/series b/debian/patches/series
index 338fbf5..a23077b 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,2 +1,3 @@
gringo-manpages.patch
gringo-include-math.patch
+gringo-solve-multi.patch
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/gringo.git
More information about the debian-science-commits
mailing list