diff --git a/deps/oblib/src/lib/alloc/object_set.cpp b/deps/oblib/src/lib/alloc/object_set.cpp index 5f29e592b8..44d0a32a4a 100644 --- a/deps/oblib/src/lib/alloc/object_set.cpp +++ b/deps/oblib/src/lib/alloc/object_set.cpp @@ -509,7 +509,8 @@ void ObjectSet::reset() if (!has_unfree) { int64_t pos = snprintf(buf, buf_len, - "label: %s, static_id: %d, static_info: %s, dynamic_info: %s", + "context: %p, label: %s, static_id: 0x%lx, static_info: %s, dynamic_info: %s", + mem_context_, label, mem_context_->get_static_id(), common::to_cstring(mem_context_->get_static_info()), diff --git a/deps/oblib/src/lib/allocator/ob_mem_leak_checker.h b/deps/oblib/src/lib/allocator/ob_mem_leak_checker.h index 149478c8d6..932adee327 100644 --- a/deps/oblib/src/lib/allocator/ob_mem_leak_checker.h +++ b/deps/oblib/src/lib/allocator/ob_mem_leak_checker.h @@ -87,7 +87,7 @@ public: { return LABEL_CHECK == ct_; } - int get_static_id() const + int64_t get_static_id() const { return static_id_; } @@ -118,7 +118,8 @@ public: char* end = (char*)memchr(cpy, '@', strlen(cpy)); if (end != nullptr) { tmp_ct = CONTEXT_CHECK; - static_id_ = atoi(end + 1); + static_id_ = 0; + sscanf(end + 1, "0x%lx", &static_id_); *end = '\0'; is_wildcard_ = 0 == STRCMP("*", cpy); } else { @@ -278,7 +279,7 @@ private: char label_[lib::AOBJECT_LABEL_SIZE + 1]; }; CheckType ct_; - int static_id_; + int64_t static_id_; bool is_wildcard_; int len_; mod_alloc_info_t malloc_info_; diff --git a/deps/oblib/src/lib/rc/context.cpp b/deps/oblib/src/lib/rc/context.cpp index 9299df3de3..3db850d027 100644 --- a/deps/oblib/src/lib/rc/context.cpp +++ b/deps/oblib/src/lib/rc/context.cpp @@ -32,10 +32,10 @@ __MemoryContext__& __MemoryContext__::root() param.set_properties(ADD_CHILD_THREAD_SAFE | ALLOC_THREAD_SAFE) .set_parallel(4) .set_mem_attr(OB_SERVER_TENANT_ID, ObModIds::OB_ROOT_CONTEXT, ObCtxIds::DEFAULT_CTX_ID); - // ObMallocAllocator to design a non-destroy mode - const static int static_id = - StaticInfos::get_instance().add(__FILENAME__, __LINE__, __FUNCTION__); - __MemoryContext__ *tmp = new (std::nothrow) __MemoryContext__(false, DynamicInfo(), nullptr, param, static_id); + // root_context相对底层,被其他static对象依赖,而static对象之间析构顺序又是不确定的, + // So here is modeled on ObMallocAllocator to design a non-destroy mode + static StaticInfo static_info{__FILENAME__, __LINE__, __FUNCTION__}; + __MemoryContext__ *tmp = new (std::nothrow) __MemoryContext__(false, DynamicInfo(), nullptr, param, &static_info); abort_unless(tmp != nullptr); int ret = tmp->init(); abort_unless(OB_SUCCESS == ret); diff --git a/deps/oblib/src/lib/rc/context.h b/deps/oblib/src/lib/rc/context.h index a81eb8517a..dd9d268b87 100644 --- a/deps/oblib/src/lib/rc/context.h +++ b/deps/oblib/src/lib/rc/context.h @@ -35,25 +35,25 @@ namespace lib { #define CURRENT_CONTEXT lib::Flow::current_ctx() #define ROOT_CONTEXT lib::MemoryContext::root() -#define CREATE_CONTEXT(args...) CREATE_CONTEXT_(CONCAT(static_id, __COUNTER__), args) +#define CREATE_CONTEXT(args...) CREATE_CONTEXT_(CONCAT(static_info, __COUNTER__), args) #define DESTROY_CONTEXT(context) lib::__MemoryContext__::destory_context(context) #define WITH_CONTEXT(context) WITH_CONTEXT_P(true, context) #define WITH_CONTEXT_P(condition, context) CONTEXT_P(condition, lib::ContextSource::WITH, context) #define CREATE_WITH_TEMP_CONTEXT(...) CREATE_WITH_TEMP_CONTEXT_P(true, __VA_ARGS__) #define CREATE_WITH_TEMP_CONTEXT_P(condition, args...) \ - CREATE_WITH_TEMP_CONTEXT_P_(CONCAT(static_id, __COUNTER__), condition, args) + CREATE_WITH_TEMP_CONTEXT_P_(CONCAT(static_info, __COUNTER__), condition, args) // The following are auxiliary macros -#define CREATE_CONTEXT_(static_id, context, args...) \ - create_context(context, lib::DynamicInfo(), args, ({ \ - const static int static_id = lib::StaticInfos::get_instance().add(__FILENAME__, __LINE__, __FUNCTION__); \ - static_id; \ +#define CREATE_CONTEXT_(static_info, context, args...) \ + create_context(context, lib::DynamicInfo(), args, ({ \ + static lib::StaticInfo static_info{__FILENAME__, __LINE__, __FUNCTION__}; \ + &static_info; \ })) #define CONTEXT_P(condition, context_source, ...) \ for (lib::_S _s{condition, __VA_ARGS__}; OB_SUCC(ret) && _s.i_-- > 0; _s.i_--) \ if (OB_SUCC(_s.get_ret())) -#define CREATE_WITH_TEMP_CONTEXT_P_(static_id, condition, ...) \ - const static int static_id = lib::StaticInfos::get_instance().add(__FILENAME__, __LINE__, __FUNCTION__); \ - CONTEXT_P(condition, lib::ContextSource::CREATE, lib::DynamicInfo(), __VA_ARGS__, static_id) +#define CREATE_WITH_TEMP_CONTEXT_P_(static_info, condition, ...) \ + static lib::StaticInfo static_info{__FILENAME__, __LINE__, __FUNCTION__}; \ + CONTEXT_P(condition, lib::ContextSource::CREATE, lib::DynamicInfo(), __VA_ARGS__, &static_info) using std::nullptr_t; using lib::ObMemAttr; @@ -233,39 +233,6 @@ struct StaticInfo { TO_STRING_KV(K(filename_), K(line_), K(function_)); }; -class StaticInfos { -public: - StaticInfos() : cnt_(0) - {} - static StaticInfos& get_instance() - { - static StaticInfos one; - return one; - } - int get_cnt() const - { - return cnt_; - } - int add(const char* filename, const int line, const char* function) - { - int pos = ATOMIC_FAA(&cnt_, 1); - abort_unless(pos < MAX_NUM && nullptr == infos_[pos].filename_); - infos_[pos] = {filename, line, function}; - const int static_id = pos; - OB_LOG(INFO, "add info", K(static_id), "info", infos_[static_id]); - return static_id; - } - const StaticInfo& get(const int static_id) const - { - return infos_[static_id]; - } - -private: - static const int MAX_NUM = 128; - StaticInfo infos_[MAX_NUM]; - int cnt_; -}; - struct DynamicInfo { DynamicInfo() : tid_(GETTID()), cid_(CO_IS_ENABLED() ? CO_ID() : 0lu), create_time_(common::ObTimeUtility::fast_current_time()) @@ -315,30 +282,36 @@ public: } public: - __MemoryContext__(const bool need_free, const DynamicInfo &di, __MemoryContext__ *parent, - ContextParam ¶m, const int static_id) - : magic_code_(-1), - seq_id_(-1), - need_free_(need_free), - tree_node_(parent != nullptr ? &parent->tree_node_ : nullptr, - param.properties_ & ADD_CHILD_THREAD_SAFE), - di_(di), - param_(param), - properties_(param.properties_), - static_id_(static_id), - p_alloc_(nullptr), - p_arena_alloc_(nullptr), - p_safe_arena_alloc_(nullptr), - parallel_alloc_(nullptr), - freeable_alloc_(nullptr), - default_allocator_(nullptr) + __MemoryContext__(const bool need_free, const DynamicInfo &di, __MemoryContext__ *parent, ContextParam ¶m, + const StaticInfo *static_info) + : magic_code_(-1), + seq_id_(-1), + need_free_(need_free), + tree_node_(parent != nullptr ? &parent->tree_node_ : nullptr, param.properties_ & ADD_CHILD_THREAD_SAFE), + di_(di), + param_(param), + properties_(param.properties_), + static_id_(reinterpret_cast(static_info)), + p_alloc_(nullptr), + p_arena_alloc_(nullptr), + p_safe_arena_alloc_(nullptr), + parallel_alloc_(nullptr), + freeable_alloc_(nullptr), + default_allocator_(nullptr) + {} + int64_t get_static_id() const { + return static_id_; } - int get_static_id() const { return static_id_; } - const DynamicInfo &get_dynamic_info() const { return di_; } - const StaticInfo &get_static_info() const { return StaticInfos::get_instance().get(static_id_); } - void *allocf(const int64_t size, - const ObMemAttr &attr=default_memattr) + const DynamicInfo &get_dynamic_info() const + { + return di_; + } + const StaticInfo &get_static_info() const + { + return *reinterpret_cast(static_id_); + } + void *allocf(const int64_t size, const ObMemAttr &attr = default_memattr) { return freeable_alloc_->alloc(size, attr); } @@ -407,12 +380,13 @@ public: return *default_allocator_; } static __MemoryContext__ &root(); - bool check_magic_code() const { return MAGIC_CODE == magic_code_; } - TO_STRING_KV(KP(this), - "static_id", static_id_, - "static_info", StaticInfos::get_instance().get(static_id_), - "dynamic info", di_, - K(properties_), K(attr_)); + bool check_magic_code() const + { + return MAGIC_CODE == magic_code_; + } + TO_STRING_KV(KP(this), "static_id", static_id_, "static_info", *reinterpret_cast(static_id_), + "dynamic info", di_, K(properties_), K(attr_)); + private: static __MemoryContext__ *node2context(TreeNode *node) { @@ -590,7 +564,7 @@ public: DynamicInfo di_; ContextParam param_; int64_t properties_; - int static_id_; + int64_t static_id_; common::ObMemAttr attr_; // Delayed member diff --git a/src/observer/ob_dump_task_generator.cpp b/src/observer/ob_dump_task_generator.cpp index 75af4e786d..865500e567 100644 --- a/src/observer/ob_dump_task_generator.cpp +++ b/src/observer/ob_dump_task_generator.cpp @@ -180,7 +180,7 @@ void ObDumpTaskGenerator::dump_memory_leak() pos += snprintf(buf + pos, buf_len - pos, "\n######## LEAK_CHECKER (origin_str = %s, label_ = %s, check_type = %d, " - "static_id_ = %d, current_ts = %ld)########\n", + "static_id_ = 0x%lx, current_ts = %ld)########\n", get_mem_leak_checker().get_str(), get_mem_leak_checker().get_label(), get_mem_leak_checker().get_check_type(), diff --git a/src/storage/ob_table_mgr.cpp b/src/storage/ob_table_mgr.cpp index 28ce519c3e..8d8ef90479 100644 --- a/src/storage/ob_table_mgr.cpp +++ b/src/storage/ob_table_mgr.cpp @@ -116,6 +116,7 @@ void ObTableMgr::stop() LOG_INFO("ObTableMgr::stop"); TG_STOP(lib::TGDefIDs::TableMgrGC); TG_WAIT(lib::TGDefIDs::TableMgrGC); + is_gc_started_ = false; LOG_INFO("timer stopped"); ObBucketWLockAllGuard guard(sstable_bucket_lock_); enable_write_log_ = false;