This is an automated email from the ASF dual-hosted git repository.
yiguolei pushed a commit to branch branch-3.0
in repository https://gitbox.apache.org/repos/asf/doris.git
The following commit(s) were added to refs/heads/branch-3.0 by this push:
new e7f095e000d branch-3.0: [bugfix](memtable) arena is freed early and
will cause use after free #46997 (#47006)
e7f095e000d is described below
commit e7f095e000d0a325300e1c871a1c8ce2469ba1ee
Author: github-actions[bot]
<41898282+github-actions[bot]@users.noreply.github.com>
AuthorDate: Wed Jan 15 14:41:20 2025 +0800
branch-3.0: [bugfix](memtable) arena is freed early and will cause use
after free #46997 (#47006)
Cherry-picked from #46997
Co-authored-by: yiguolei <[email protected]>
---
be/src/olap/memtable.cpp | 52 ++++++++++++++++++++++++++----------------------
1 file changed, 28 insertions(+), 24 deletions(-)
diff --git a/be/src/olap/memtable.cpp b/be/src/olap/memtable.cpp
index 69c886d76ef..46482be7169 100644
--- a/be/src/olap/memtable.cpp
+++ b/be/src/olap/memtable.cpp
@@ -138,6 +138,34 @@ void MemTable::_init_agg_functions(const
vectorized::Block* block) {
MemTable::~MemTable() {
SCOPED_SWITCH_THREAD_MEM_TRACKER_LIMITER(_query_thread_context.query_mem_tracker);
+ {
+ SCOPED_CONSUME_MEM_TRACKER(_mem_tracker);
+ g_memtable_cnt << -1;
+ if (_keys_type != KeysType::DUP_KEYS) {
+ for (auto it = _row_in_blocks.begin(); it != _row_in_blocks.end();
it++) {
+ if (!(*it)->has_init_agg()) {
+ continue;
+ }
+ // We should release agg_places here, because they are not
released when a
+ // load is canceled.
+ for (size_t i = _tablet_schema->num_key_columns(); i <
_num_columns; ++i) {
+ auto function = _agg_functions[i];
+ DCHECK(function != nullptr);
+ function->destroy((*it)->agg_places(i));
+ }
+ }
+ }
+ std::for_each(_row_in_blocks.begin(), _row_in_blocks.end(),
+ std::default_delete<RowInBlock>());
+ // Arena has to be destroyed after agg state, because some agg state's
memory may be
+ // allocated in arena.
+ _arena.reset();
+ _vec_row_comparator.reset();
+ _row_in_blocks.clear();
+ _agg_functions.clear();
+ _input_mutable_block.clear();
+ _output_mutable_block.clear();
+ }
if (_is_flush_success) {
// If the memtable is flush success, then its memtracker's consumption
should be 0
if (_mem_tracker->consumption() != 0 &&
config::crash_in_memory_tracker_inaccurate) {
@@ -145,28 +173,6 @@ MemTable::~MemTable() {
<< _mem_tracker->consumption();
}
}
- g_memtable_cnt << -1;
- if (_keys_type != KeysType::DUP_KEYS) {
- for (auto it = _row_in_blocks.begin(); it != _row_in_blocks.end();
it++) {
- if (!(*it)->has_init_agg()) {
- continue;
- }
- // We should release agg_places here, because they are not
released when a
- // load is canceled.
- for (size_t i = _tablet_schema->num_key_columns(); i <
_num_columns; ++i) {
- auto function = _agg_functions[i];
- DCHECK(function != nullptr);
- function->destroy((*it)->agg_places(i));
- }
- }
- }
- std::for_each(_row_in_blocks.begin(), _row_in_blocks.end(),
std::default_delete<RowInBlock>());
- _arena.reset();
- _vec_row_comparator.reset();
- _row_in_blocks.clear();
- _agg_functions.clear();
- _input_mutable_block.clear();
- _output_mutable_block.clear();
}
int RowInBlockComparator::operator()(const RowInBlock* left, const RowInBlock*
right) const {
@@ -518,8 +524,6 @@ Status
MemTable::_to_block(std::unique_ptr<vectorized::Block>* res) {
RETURN_IF_ERROR(_sort_by_cluster_keys());
}
_input_mutable_block.clear();
- // After to block, all data in arena is saved in the block
- _arena.reset();
*res = vectorized::Block::create_unique(_output_mutable_block.to_block());
return Status::OK();
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]