From 4b0ddb68b4e76420358589213bc400155fa12e43 Mon Sep 17 00:00:00 2001 From: Lei YU Date: Fri, 25 Jan 2019 16:43:50 +0800 Subject: Set init_priority attribute for global variables in shared lib The code gets unspecified initializatio order for the global/static variables in a shared library. If unluck, a global/static variable may be initialized in *constructor* function, and then initialized by the default contructor. For exmaple, if `std::unique_ptr var{nullptr};` is initialized in constructor function, below init order may occur: 1. It is initialized in constructor; 2. Then it is initialized as nullptr; And eventually when the code is to use the variable, we got nullptr. We met such issues before on openbmc/openbmc#1581, and the technical details could be found at [this SO question][1] and [this gcc email][2] The solution is to specify the init_priority attribute, to make the global/staic variables inititalize earlier than the contructors. [1]: https://stackoverflow.com/questions/43941159/global-static-variables-initialization-issue-with-attribute-constructor-i [2]: https://gcc.gnu.org/ml/gcc-patches/2017-03/msg00863.html Change-Id: I901a6a5cddec12aec9512fe58b16735fa2ad90d7 Signed-off-by: Lei YU --- chassishandler.cpp | 3 ++- read_fru_data.cpp | 3 ++- user_channel/channel_mgmt.cpp | 3 ++- user_channel/user_mgmt.cpp | 9 ++++++--- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/chassishandler.cpp b/chassishandler.cpp index 068ad89..c9885bd 100644 --- a/chassishandler.cpp +++ b/chassishandler.cpp @@ -54,7 +54,8 @@ namespace filesystem = std::experimental::filesystem; #define SET_PARM_BOOT_FLAGS_VALID_ONE_TIME 0x80 #define SET_PARM_BOOT_FLAGS_VALID_PERMANENT 0xC0 -std::unique_ptr identifyTimer = nullptr; +std::unique_ptr identifyTimer + __attribute__((init_priority(101))); constexpr size_t SIZE_MAC = 18; constexpr size_t SIZE_BOOT_OPTION = (uint8_t) diff --git a/read_fru_data.cpp b/read_fru_data.cpp index 2bb111f..94b2478 100644 --- a/read_fru_data.cpp +++ b/read_fru_data.cpp @@ -23,7 +23,8 @@ namespace variant_ns = sdbusplus::message::variant_ns; using namespace phosphor::logging; using InternalFailure = sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; -std::unique_ptr matchPtr(nullptr); +std::unique_ptr matchPtr + __attribute__((init_priority(101))); static constexpr auto INV_INTF = "xyz.openbmc_project.Inventory.Manager"; static constexpr auto OBJ_PATH = "/xyz/openbmc_project/inventory"; diff --git a/user_channel/channel_mgmt.cpp b/user_channel/channel_mgmt.cpp index 585d441..9374931 100644 --- a/user_channel/channel_mgmt.cpp +++ b/user_channel/channel_mgmt.cpp @@ -89,7 +89,8 @@ static constexpr const uint8_t defaultAuthType = static constexpr const bool defaultIsIpmiState = false; static constexpr size_t smallChannelSize = 64; -std::unique_ptr chPropertiesSignal(nullptr); +std::unique_ptr chPropertiesSignal + __attribute__((init_priority(101))); // String mappings use in JSON config file static std::unordered_map mediumTypeMap = { diff --git a/user_channel/user_mgmt.cpp b/user_channel/user_mgmt.cpp index 0b86823..42a1e09 100644 --- a/user_channel/user_mgmt.cpp +++ b/user_channel/user_mgmt.cpp @@ -116,9 +116,12 @@ using NoResource = using InternalFailure = sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; -std::unique_ptr userUpdatedSignal(nullptr); -std::unique_ptr userMgrRenamedSignal(nullptr); -std::unique_ptr userPropertiesSignal(nullptr); +std::unique_ptr userUpdatedSignal + __attribute__((init_priority(101))); +std::unique_ptr userMgrRenamedSignal + __attribute__((init_priority(101))); +std::unique_ptr userPropertiesSignal + __attribute__((init_priority(101))); // TODO: Below code can be removed once it is moved to common layer libmiscutil std::string getUserService(sdbusplus::bus::bus& bus, const std::string& intf, -- cgit v1.2.1