diff options
author | Aina Niemetz <aina.niemetz@gmail.com> | 2021-03-09 12:59:13 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-09 20:59:13 +0000 |
commit | 4da1a65539d3c7481a1f4121f0e9bc09694f889d (patch) | |
tree | e32d1fb96bd30dd98bb73654ac6c30ae51c58cd5 /src/context | |
parent | ba06bb6c4cd2b16437fcfe5fe29acb6c8c890649 (diff) |
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.
Diffstat (limited to 'src/context')
-rw-r--r-- | src/context/context.cpp | 16 |
1 files 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 " |