From 4da1a65539d3c7481a1f4121f0e9bc09694f889d Mon Sep 17 00:00:00 2001 From: Aina Niemetz Date: Tue, 9 Mar 2021 12:59:13 -0800 Subject: [PATCH] ContextObj::destroy(): Guard against invalid use. (#6082) We do not allow that a context object is invalid on destruction. This guards against invalid use as described in #2607. Note that #2607 proposed to skip invalid objects on destruction. We now rather do not allow for such a case to occur at all. --- src/context/context.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/src/context/context.cpp b/src/context/context.cpp index eaadb9f98..06485c0ba 100644 --- a/src/context/context.cpp +++ b/src/context/context.cpp @@ -209,6 +209,7 @@ ContextObj* ContextObj::restoreAndContinue() Debug("context") << "NULL restore object! " << this << std::endl; pContextObjNext = d_pContextObjNext; + d_pScope = nullptr; // Nothing else to do } else { @@ -237,21 +238,30 @@ ContextObj* ContextObj::restoreAndContinue() void ContextObj::destroy() { + /* The object to destroy must be valid, i.e., its current state must belong + * to a scope. We remove the object and its previous versions from their + * respective scopes below. If this assertion is failing, you may have + * created an object at a non-zero level and let it outlive the destruction + * of that level. */ + Assert(d_pScope != nullptr); /* Context can be big and complicated, so we only want to process this output * if we're really going to use it. (Same goes below.) */ Debug("context") << "before destroy " << this << " (level " << getLevel() << "):" << std::endl << *getContext() << std::endl; - for(;;) { + for (;;) + { // If valgrind reports invalid writes on the next few lines, // here's a hint: make sure all classes derived from ContextObj in // the system properly call destroy() in their destructors. // That's needed to maintain this linked list properly. - if(next() != NULL) { + if (next() != nullptr) + { next()->prev() = prev(); } *prev() = next(); - if(d_pContextObjRestore == NULL) { + if (d_pContextObjRestore == nullptr) + { break; } Debug("context") << "in destroy " << this << ", restore object is " -- 2.30.2