From: Mykola Golub Date: Fri, 18 Dec 2015 15:10:33 +0000 (+0200) Subject: rbd: fix "static initialization order fiasco" X-Git-Tag: v10.0.3~202^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=b21152a27fe06afec04fc38e10a7b54e465c7abe;p=ceph.git rbd: fix "static initialization order fiasco" The order in which static objects in different compilation units are initialized is undefined. Use static functions as a workaround. Signed-off-by: Mykola Golub --- diff --git a/src/tools/rbd/Shell.cc b/src/tools/rbd/Shell.cc index 57af89a567a6..76aa8ed52a14 100644 --- a/src/tools/rbd/Shell.cc +++ b/src/tools/rbd/Shell.cc @@ -66,8 +66,17 @@ std::string format_option_suffix( } // anonymous namespace -std::vector Shell::s_actions; -std::set Shell::s_switch_arguments; +std::vector& Shell::get_actions() { + static std::vector actions; + + return actions; +} + +std::set& Shell::get_switch_arguments() { + static std::set switch_arguments; + + return switch_arguments; +} int Shell::execute(int arg_count, const char **arg_values) { @@ -187,9 +196,10 @@ void Shell::get_command_spec(const std::vector &arguments, } else if (arg[0] == '-') { // if the option is not a switch, skip its value if (arg.size() >= 2 && - (arg[1] == '-' || s_switch_arguments.count(arg.substr(1, 1)) == 0) && + (arg[1] == '-' || + get_switch_arguments().count(arg.substr(1, 1)) == 0) && (arg[1] != '-' || - s_switch_arguments.count(arg.substr(2, std::string::npos)) == 0) && + get_switch_arguments().count(arg.substr(2, std::string::npos)) == 0) && at::SWITCH_ARGUMENTS.count(arg.substr(2, std::string::npos)) == 0 && arg.find('=') == std::string::npos) { ++i; @@ -202,8 +212,8 @@ void Shell::get_command_spec(const std::vector &arguments, Shell::Action *Shell::find_action(const CommandSpec &command_spec, CommandSpec **matching_spec) { - for (size_t i = 0; i < s_actions.size(); ++i) { - Action *action = s_actions[i]; + for (size_t i = 0; i < get_actions().size(); ++i) { + Action *action = get_actions()[i]; if (action->command_spec.size() <= command_spec.size()) { if (std::includes(action->command_spec.begin(), action->command_spec.end(), @@ -277,7 +287,7 @@ void Shell::print_help() { << "Command-line interface for managing Ceph RBD images." << std::endl << std::endl; - std::vector actions(s_actions); + std::vector actions(get_actions()); std::sort(actions.begin(), actions.end(), [](Action *lhs, Action *rhs) { return lhs->command_spec < rhs->command_spec; }); @@ -368,8 +378,8 @@ void Shell::print_bash_completion(const CommandSpec &command_spec) { print_bash_completion_options(command_opts); } else { std::cout << "|help"; - for (size_t i = 0; i < s_actions.size(); ++i) { - Action *action = s_actions[i]; + for (size_t i = 0; i < get_actions().size(); ++i) { + Action *action = get_actions()[i]; std::cout << "|" << joinify(action->command_spec.begin(), action->command_spec.end(), " "); diff --git a/src/tools/rbd/Shell.h b/src/tools/rbd/Shell.h index 4a21325b3d5f..b65483eee483 100644 --- a/src/tools/rbd/Shell.h +++ b/src/tools/rbd/Shell.h @@ -36,22 +36,22 @@ public: : command_spec(command_spec), alias_command_spec(alias_command_spec), description(description), help(help), get_arguments(args), execute(execute) { - Shell::s_actions.push_back(this); + Shell::get_actions().push_back(this); } }; struct SwitchArguments { SwitchArguments(const std::initializer_list &arguments) { - Shell::s_switch_arguments.insert(arguments.begin(), arguments.end()); + Shell::get_switch_arguments().insert(arguments.begin(), arguments.end()); } }; int execute(int arg_count, const char **arg_values); private: - static std::vector s_actions; - static std::set s_switch_arguments; + static std::vector& get_actions(); + static std::set& get_switch_arguments(); void get_command_spec(const std::vector &arguments, std::vector *command_spec);