diff --git a/client/BUILD.gn b/client/BUILD.gn index ddd521f2..9d8b736f 100644 --- a/client/BUILD.gn +++ b/client/BUILD.gn @@ -52,7 +52,11 @@ static_library("client") { } if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) { - sources += [ "crashpad_info_note.S" ] + sources += [ + "client_argv_handling.cc", + "client_argv_handling.h", + "crashpad_info_note.S", + ] } if (crashpad_is_win) { @@ -64,9 +68,7 @@ static_library("client") { } if (crashpad_is_fuchsia) { - sources += [ - "crashpad_client_fuchsia.cc", - ] + sources += [ "crashpad_client_fuchsia.cc" ] } if (crashpad_is_linux || crashpad_is_android || crashpad_is_fuchsia) { diff --git a/client/client_argv_handling.cc b/client/client_argv_handling.cc new file mode 100644 index 00000000..9b813b1c --- /dev/null +++ b/client/client_argv_handling.cc @@ -0,0 +1,74 @@ +// Copyright 2018 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#include "client/client_argv_handling.h" + +#include "base/strings/stringprintf.h" + +namespace crashpad { + +namespace { + +std::string FormatArgumentString(const std::string& name, + const std::string& value) { + return base::StringPrintf("--%s=%s", name.c_str(), value.c_str()); +} + +} // namespace + +void BuildHandlerArgvStrings( + const base::FilePath& handler, + const base::FilePath& database, + const base::FilePath& metrics_dir, + const std::string& url, + const std::map& annotations, + const std::vector& arguments, + std::vector* argv_strings) { + argv_strings->clear(); + + argv_strings->push_back(handler.value()); + for (const auto& argument : arguments) { + argv_strings->push_back(argument); + } + + if (!database.empty()) { + argv_strings->push_back(FormatArgumentString("database", database.value())); + } + + if (!metrics_dir.empty()) { + argv_strings->push_back( + FormatArgumentString("metrics-dir", metrics_dir.value())); + } + + if (!url.empty()) { + argv_strings->push_back(FormatArgumentString("url", url)); + } + + for (const auto& kv : annotations) { + argv_strings->push_back( + FormatArgumentString("annotation", kv.first + '=' + kv.second)); + } +} + +void ConvertArgvStrings(const std::vector& argv_strings, + std::vector* argv) { + argv->clear(); + argv->reserve(argv_strings.size() + 1); + for (const auto& arg : argv_strings) { + argv->push_back(arg.c_str()); + } + argv->push_back(nullptr); +} + +} // namespace crashpad diff --git a/client/client_argv_handling.h b/client/client_argv_handling.h new file mode 100644 index 00000000..0ef3a154 --- /dev/null +++ b/client/client_argv_handling.h @@ -0,0 +1,53 @@ +// Copyright 2018 The Crashpad Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#ifndef CRASHPAD_CLIENT_CLIENT_ARGV_HANDLING_H_ +#define CRASHPAD_CLIENT_CLIENT_ARGV_HANDLING_H_ + +#include +#include +#include + +#include "base/files/file_path.h" + +namespace crashpad { + +//! \brief Builds a vector of arguments suitable for invoking a handler process +//! based on arguments passed to StartHandler-type(). +//! +//! See StartHandlerAtCrash() for documentation on the input arguments. +//! +//! \param[out] A argv_strings vector of arguments suitable for starting the +//! handler with. +void BuildHandlerArgvStrings( + const base::FilePath& handler, + const base::FilePath& database, + const base::FilePath& metrics_dir, + const std::string& url, + const std::map& annotations, + const std::vector& arguments, + std::vector* argv_strings); + +//! \brief Flattens a string vector into a const char* vector suitable for use +//! in an exec() call. +//! +//! \param[in] argv_strings Arguments to be passed to child process, typically +//! created by BuildHandlerArgvStrings(). +//! \param[out] argv argv suitable for starting the child process. +void ConvertArgvStrings(const std::vector& argv_strings, + std::vector* argv); + +} // namespace crashpad + +#endif // CRASHPAD_CLIENT_CLIENT_ARGV_HANDLING_H_ diff --git a/client/crashpad_client_linux.cc b/client/crashpad_client_linux.cc index 22f7e3d8..4d0d111b 100644 --- a/client/crashpad_client_linux.cc +++ b/client/crashpad_client_linux.cc @@ -24,6 +24,7 @@ #include "base/logging.h" #include "base/strings/stringprintf.h" +#include "client/client_argv_handling.h" #include "util/file/file_io.h" #include "util/linux/exception_handler_client.h" #include "util/linux/exception_information.h" @@ -36,11 +37,6 @@ namespace crashpad { namespace { -std::string FormatArgumentString(const std::string& name, - const std::string& value) { - return base::StringPrintf("--%s=%s", name.c_str(), value.c_str()); -} - std::string FormatArgumentInt(const std::string& name, int value) { return base::StringPrintf("--%s=%d", name.c_str(), value); } @@ -49,50 +45,6 @@ std::string FormatArgumentAddress(const std::string& name, void* addr) { return base::StringPrintf("--%s=%p", name.c_str(), addr); } -void BuildHandlerArgvStrings( - const base::FilePath& handler, - const base::FilePath& database, - const base::FilePath& metrics_dir, - const std::string& url, - const std::map& annotations, - const std::vector& arguments, - std::vector* argv_strings) { - argv_strings->clear(); - - argv_strings->push_back(handler.value()); - for (const auto& argument : arguments) { - argv_strings->push_back(argument); - } - - if (!database.empty()) { - argv_strings->push_back(FormatArgumentString("database", database.value())); - } - - if (!metrics_dir.empty()) { - argv_strings->push_back( - FormatArgumentString("metrics-dir", metrics_dir.value())); - } - - if (!url.empty()) { - argv_strings->push_back(FormatArgumentString("url", url)); - } - - for (const auto& kv : annotations) { - argv_strings->push_back( - FormatArgumentString("annotation", kv.first + '=' + kv.second)); - } -} - -void ConvertArgvStrings(const std::vector& argv_strings, - std::vector* argv) { - argv->clear(); - argv->reserve(argv_strings.size() + 1); - for (const auto& arg : argv_strings) { - argv->push_back(arg.c_str()); - } - argv->push_back(nullptr); -} - class SignalHandler { public: virtual void HandleCrashFatal(int signo,