From: Changgyu Choi Date: Wed, 22 May 2024 03:56:36 +0000 (+0900) Subject: Fix crash issue X-Git-Tag: accepted/tizen/unified/20240701.055744~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f3ed7f2c55468236f4f8cdad407d915a87c22767;p=platform%2Fcore%2Fapi%2Fpreference.git Fix crash issue In the case of using the preference api after the global resource is destroyed, a problem occurs by accessing the destroyed pref object. This patch fixes that issue. 01-01 12:34:23.143+0900 I/CAPI_APPFW_PREFERENCE(P 5722, T 5722): file-backend-internal.cc: ~FileBackend(33) > 01-01 12:34:23.143+0900 I/CAPI_APPFW_PREFERENCE(P 5722, T 5722): file-backend-internal.cc: RemoveWatch(173) > 01-01 12:34:23.206+0900 I/CAPI_APPFW_PREFERENCE(P 5722, T 5742): stub.cc: preference_unset_changed_cb(317) > Change-Id: I685c3d39ac0ee6e674d91f44b14c8d965edd08bf Signed-off-by: Changgyu Choi --- diff --git a/preference/stub.cc b/preference/stub.cc index 5dd96b9..dbdafd3 100644 --- a/preference/stub.cc +++ b/preference/stub.cc @@ -46,6 +46,10 @@ class PrefExt : public preference::internal::Preference, PrefExt() : Preference(this) { } + ~PrefExt() { + _I(""); + } + int AddWatch(const char* key, preference_changed_cb cb, void* user_data) { std::lock_guard lock(GetMutex()); if (Preference::AddWatch(key) < 0) @@ -103,7 +107,12 @@ class PrefExt : public preference::internal::Preference, mutable std::recursive_mutex mutex_; }; -PrefExt pref; +PrefExt* pref = new PrefExt(); + +__attribute__((destructor)) static void destructor() { + delete pref; + pref = nullptr; +} } // namespace @@ -113,7 +122,12 @@ extern "C" API int preference_set_int(const char* key, int intval) { return PREFERENCE_ERROR_INVALID_PARAMETER; } - int ret = pref.SetInt(key, intval); + if (pref == nullptr) { + _E("global resource was destroyed"); + return PREFERENCE_ERROR_IO_ERROR; + } + + int ret = pref->SetInt(key, intval); if (ret < 0) { _E("Failed to set integer value"); return PREFERENCE_ERROR_IO_ERROR; @@ -129,7 +143,12 @@ extern "C" API int preference_set_boolean(const char* key, bool boolval) { return PREFERENCE_ERROR_INVALID_PARAMETER; } - int ret = pref.SetBoolean(key, boolval); + if (pref == nullptr) { + _E("global resource was destroyed"); + return PREFERENCE_ERROR_IO_ERROR; + } + + int ret = pref->SetBoolean(key, boolval); if (ret < 0) { _E("Failed to set boolean value"); return PREFERENCE_ERROR_IO_ERROR; @@ -145,7 +164,12 @@ extern "C" API int preference_set_double(const char* key, double dblval) { return PREFERENCE_ERROR_INVALID_PARAMETER; } - int ret = pref.SetDouble(key, dblval); + if (pref == nullptr) { + _E("global resource was destroyed"); + return PREFERENCE_ERROR_IO_ERROR; + } + + int ret = pref->SetDouble(key, dblval); if (ret < 0) { _E("Failed to set double value"); return PREFERENCE_ERROR_IO_ERROR; @@ -162,7 +186,12 @@ extern "C" API int preference_set_string(const char* key, const char* strval) { return PREFERENCE_ERROR_INVALID_PARAMETER; } - int ret = pref.SetString(key, strval); + if (pref == nullptr) { + _E("global resource was destroyed"); + return PREFERENCE_ERROR_IO_ERROR; + } + + int ret = pref->SetString(key, strval); if (ret < 0) { _E("Failed to set string value"); return PREFERENCE_ERROR_IO_ERROR; @@ -178,11 +207,16 @@ extern "C" API int preference_get_int(const char* key, int* intval) { return PREFERENCE_ERROR_INVALID_PARAMETER; } - if (!pref.IsExisting(key)) + if (pref == nullptr) { + _E("global resource was destroyed"); + return PREFERENCE_ERROR_IO_ERROR; + } + + if (!pref->IsExisting(key)) return PREFERENCE_ERROR_NO_KEY; try { - *intval = pref.GetInt(key); + *intval = pref->GetInt(key); } catch (const preference::internal::Exception& e) { return e.GetErrorCode(); } @@ -197,11 +231,16 @@ extern "C" API int preference_get_boolean(const char* key, bool* boolval) { return PREFERENCE_ERROR_INVALID_PARAMETER; } - if (!pref.IsExisting(key)) + if (pref == nullptr) { + _E("global resource was destroyed"); + return PREFERENCE_ERROR_IO_ERROR; + } + + if (!pref->IsExisting(key)) return PREFERENCE_ERROR_NO_KEY; try { - *boolval = pref.GetBoolean(key); + *boolval = pref->GetBoolean(key); } catch (const preference::internal::Exception& e) { return e.GetErrorCode(); } @@ -216,11 +255,16 @@ extern "C" API int preference_get_double(const char* key, double* dblval) { return PREFERENCE_ERROR_INVALID_PARAMETER; } - if (!pref.IsExisting(key)) + if (pref == nullptr) { + _E("global resource was destroyed"); + return PREFERENCE_ERROR_IO_ERROR; + } + + if (!pref->IsExisting(key)) return PREFERENCE_ERROR_NO_KEY; try { - *dblval = pref.GetDouble(key); + *dblval = pref->GetDouble(key); } catch (const preference::internal::Exception& e) { return e.GetErrorCode(); } @@ -235,11 +279,16 @@ extern "C" API int preference_get_string(const char* key, char** value) { return PREFERENCE_ERROR_INVALID_PARAMETER; } - if (!pref.IsExisting(key)) + if (pref == nullptr) { + _E("global resource was destroyed"); + return PREFERENCE_ERROR_IO_ERROR; + } + + if (!pref->IsExisting(key)) return PREFERENCE_ERROR_NO_KEY; try { - *value = strdup(pref.GetString(key).c_str()); + *value = strdup(pref->GetString(key).c_str()); } catch (const preference::internal::Exception& e) { return e.GetErrorCode(); } @@ -254,12 +303,17 @@ extern "C" API int preference_remove(const char* key) { return PREFERENCE_ERROR_INVALID_PARAMETER; } - if (!pref.IsExisting(key)) { + if (pref == nullptr) { + _E("global resource was destroyed"); + return PREFERENCE_ERROR_IO_ERROR; + } + + if (!pref->IsExisting(key)) { _E("%s doesn't exist", key); return PREFERENCE_ERROR_NO_KEY; } - int ret = pref.Remove(key); + int ret = pref->Remove(key); if (ret < 0) { _E("Failed to remove key(%s)", key); return PREFERENCE_ERROR_IO_ERROR; @@ -275,13 +329,23 @@ extern "C" API int preference_is_existing(const char* key, bool* exist) { return PREFERENCE_ERROR_INVALID_PARAMETER; } - *exist = pref.IsExisting(key); + if (pref == nullptr) { + _E("global resource was destroyed"); + return PREFERENCE_ERROR_IO_ERROR; + } + + *exist = pref->IsExisting(key); SECURE_LOGD("key(%s), existence(%d)", key, *exist); return PREFERENCE_ERROR_NONE; } extern "C" API int preference_remove_all(void) { - int ret = pref.RemoveAll(); + if (pref == nullptr) { + _E("global resource was destroyed"); + return PREFERENCE_ERROR_IO_ERROR; + } + + int ret = pref->RemoveAll(); if (ret < 0) { _E("Failed to delete all keys"); return PREFERENCE_ERROR_IO_ERROR; @@ -298,12 +362,17 @@ extern "C" API int preference_set_changed_cb(const char* key, return PREFERENCE_ERROR_INVALID_PARAMETER; } - if (!pref.IsExisting(key)) { + if (pref == nullptr) { + _E("global resource was destroyed"); + return PREFERENCE_ERROR_IO_ERROR; + } + + if (!pref->IsExisting(key)) { _E("Failed to find key(%s)", key); return PREFERENCE_ERROR_NO_KEY; } - int ret = pref.AddWatch(key, callback, user_data); + int ret = pref->AddWatch(key, callback, user_data); if (ret < 0) { _E("Failed to add watch"); return PREFERENCE_ERROR_OUT_OF_MEMORY; @@ -319,12 +388,17 @@ extern "C" API int preference_unset_changed_cb(const char* key) { return PREFERENCE_ERROR_INVALID_PARAMETER; } - if (!pref.IsExisting(key)) { + if (pref == nullptr) { + _E("global resource was destroyed"); + return PREFERENCE_ERROR_IO_ERROR; + } + + if (!pref->IsExisting(key)) { _E("Failed to find key(%s)", key); return PREFERENCE_ERROR_NO_KEY; } - int ret = pref.RemoveWatch(key); + int ret = pref->RemoveWatch(key); if (ret < 0) { _E("Failed to remove watch"); return PREFERENCE_ERROR_NO_KEY; @@ -341,7 +415,12 @@ extern "C" API int preference_foreach_item(preference_item_cb callback, return PREFERENCE_ERROR_INVALID_PARAMETER; } - auto keys = pref.GetKeys(); + if (pref == nullptr) { + _E("global resource was destroyed"); + return PREFERENCE_ERROR_IO_ERROR; + } + + auto keys = pref->GetKeys(); for (auto& i : keys) { if (!callback(i.c_str(), user_data)) break; @@ -357,12 +436,17 @@ extern "C" API int preference_get_type(const char* key, return PREFERENCE_ERROR_INVALID_PARAMETER; } - if (!pref.IsExisting(key)) { + if (pref == nullptr) { + _E("global resource was destroyed"); + return PREFERENCE_ERROR_IO_ERROR; + } + + if (!pref->IsExisting(key)) { *type = PREFERENCE_TYPE_NONE; return PREFERENCE_ERROR_NONE; } - *type = static_cast(pref.GetType(key)); + *type = static_cast(pref->GetType(key)); SECURE_LOGD("key(%s), type(%d)", key, *type); return PREFERENCE_ERROR_NONE; }