This is an automated email from the ASF dual-hosted git repository.
liaoxin pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/master by this push:
new 00bdff9381f [fix](cloud) Fix CloudRowsetWriter vtable use-after-free
in delete bitmap task (#60528)
00bdff9381f is described below
commit 00bdff9381fec589fbe1857c446232909e631bf1
Author: Xin Liao <[email protected]>
AuthorDate: Thu Feb 12 14:34:24 2026 +0800
[fix](cloud) Fix CloudRowsetWriter vtable use-after-free in delete bitmap
task (#60528)
When CloudRowsetWriter is destroyed while a delete bitmap task is still
pending in the thread pool, the lambda may execute after
CloudRowsetWriter's destructor runs but before BaseBetaRowsetWriter's
destructor completes.
At this point, the vtable pointer has already been changed to point to
BaseBetaRowsetWriter's vtable, causing _build_rowset_meta() virtual call
to resolve to BaseBetaRowsetWriter::_build_rowset_meta instead of
CloudRowsetWriter::_build_rowset_meta.
This causes _collect_all_packed_slice_locations() to not be called,
resulting in missing packed file location info in rowset meta, which
leads to NOT_FOUND errors when opening segment files.
Fix by canceling _calc_delete_bitmap_token in CloudRowsetWriter's
destructor, consistent with BetaRowsetWriter's destructor behavior.
---
be/src/cloud/cloud_rowset_writer.cpp | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/be/src/cloud/cloud_rowset_writer.cpp
b/be/src/cloud/cloud_rowset_writer.cpp
index d4a9fbce7e2..0c1b79392e9 100644
--- a/be/src/cloud/cloud_rowset_writer.cpp
+++ b/be/src/cloud/cloud_rowset_writer.cpp
@@ -26,7 +26,16 @@ namespace doris {
CloudRowsetWriter::CloudRowsetWriter(CloudStorageEngine& engine) :
_engine(engine) {}
-CloudRowsetWriter::~CloudRowsetWriter() = default;
+CloudRowsetWriter::~CloudRowsetWriter() {
+ // Must cancel any pending delete bitmap tasks before destruction.
+ // Otherwise, the lambda in _generate_delete_bitmap may execute after the
+ // CloudRowsetWriter destructor runs but before BaseBetaRowsetWriter
destructor,
+ // causing virtual function calls to resolve to
BaseBetaRowsetWriter::_build_rowset_meta
+ // instead of CloudRowsetWriter::_build_rowset_meta (use-after-free on
vtable).
+ if (_calc_delete_bitmap_token != nullptr) {
+ _calc_delete_bitmap_token->cancel();
+ }
+}
Status CloudRowsetWriter::init(const RowsetWriterContext&
rowset_writer_context) {
_context = rowset_writer_context;
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]