Le 20/12/2025 à 04:03, Koji Yokota a écrit :
2025/12/20 1:44、Jean-Marc Lasgouttes <[email protected]>のメール:
It would be interesting to see what theBufferList().isLoaded(buf) and theBufferList().isInternal(buf) return in the helper destructor. The question is to know how it is possible to detect that the buffer has been destroyed.

Dear Koji,

I think that I know what happens: the UndoGroupHelper is called after the destruction of the LyX singleton (which hold all global variables) and therefore it is the buffer list itself that does not exist anymore.

The attached patch tries to handle that. Can you give it a go?

JMarc

diff --git a/src/BufferList.cpp b/src/BufferList.cpp
index 757bf46cf7..45485d59fc 100644
--- a/src/BufferList.cpp
+++ b/src/BufferList.cpp
@@ -42,13 +42,16 @@ namespace Alert = lyx::frontend::Alert;
 
 
 BufferList::BufferList()
-{}
+{
+	exists_ = true;
+}
 
 
 BufferList::~BufferList()
 {
 	for (Buffer * buf : binternal)
 		delete buf;
+	exists_ = false;
 }
 
 
diff --git a/src/BufferList.h b/src/BufferList.h
index 1384467c73..90725b37ba 100644
--- a/src/BufferList.h
+++ b/src/BufferList.h
@@ -131,6 +131,9 @@ public:
 	void invalidateConverterCache() const;
 	//@}
 
+	// Do we have a usable BufferList object?
+	static bool exists() { return exists_; }
+
 private:
 	/// create a new buffer
 	/// \return 0 if the Buffer creation is not possible for whatever reason.
@@ -146,6 +149,9 @@ private:
 	BufferStorage bstore;
 	/// storage of all internal buffers used for cut&paste, etc.
 	BufferStorage binternal;
+
+	/// has the (unique) BufferList instance been created?
+	static inline bool exists_ = false;
 };
 
 /// Implementation is in LyX.cpp
diff --git a/src/Undo.cpp b/src/Undo.cpp
index 69d85a7e5f..f2022c798e 100644
--- a/src/Undo.cpp
+++ b/src/Undo.cpp
@@ -713,9 +713,15 @@ UndoGroupHelper::UndoGroupHelper(CursorData & cur) : d(new UndoGroupHelper::Impl
 
 UndoGroupHelper::~UndoGroupHelper()
 {
-	for (Buffer * buf : d->buffers_)
-		if (theBufferList().isLoaded(buf) || theBufferList().isInternal(buf))
-			buf->undo().endUndoGroup();
+	/**
+	 * It may happen (in macOS, for instance) that the LyX singleton
+	 * is destroyed before this destructor is called. In this case,
+	 * one should not try, or need, to access the BufferList object.
+	 */
+	if (BufferList::exists())
+		for (Buffer * buf : d->buffers_)
+			if (theBufferList().isLoaded(buf) || theBufferList().isInternal(buf))
+				buf->undo().endUndoGroup();
 	delete d;
 }
 
-- 
lyx-devel mailing list
[email protected]
https://lists.lyx.org/mailman/listinfo/lyx-devel

Reply via email to