From 133317eeec0ad66f2ffc3bf822b17fed0ecf2819 Mon Sep 17 00:00:00 2001 From: Marshall Greenblatt Date: Wed, 25 Jun 2014 19:47:06 +0000 Subject: [PATCH] Linux: Fix crash due to Chromium modifying the |argv| passed to main() (issue #620). git-svn-id: https://chromiumembedded.googlecode.com/svn/trunk@1750 5089003a-bbd8-11dd-ad1f-f1f9622dbc98 --- tests/cefclient/util.h | 28 ++++++++++++++++++++++++++++ tests/unittests/run_all_unittests.cc | 18 ++++++++++++++---- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/tests/cefclient/util.h b/tests/cefclient/util.h index ba0305c1c..4d9845772 100644 --- a/tests/cefclient/util.h +++ b/tests/cefclient/util.h @@ -6,6 +6,10 @@ #define CEF_TESTS_CEFCLIENT_UTIL_H_ #pragma once +#include +#include +#include + #include "include/cef_task.h" #if defined(OS_WIN) @@ -34,4 +38,28 @@ #define REQUIRE_IO_THREAD() ASSERT(CefCurrentlyOn(TID_IO)); #define REQUIRE_FILE_THREAD() ASSERT(CefCurrentlyOn(TID_FILE)); +// Helper class to manage a scoped copy of |argv|. +class ScopedArgArray { + public: + ScopedArgArray(int argc, char* argv[]) { + array_ = new char*[argc]; + for (int i = 0; i < argc; ++i) { + values_.push_back(argv[i]); + array_[i] = const_cast(values_[i].c_str()); + } + } + ~ScopedArgArray() { + delete [] array_; + } + + char** array() const { return array_; } + + private: + char** array_; + + // Keep values in a vector separate from |array_| because various users may + // modify |array_| and we still want to clean up memory properly. + std::vector values_; +}; + #endif // CEF_TESTS_CEFCLIENT_UTIL_H_ diff --git a/tests/unittests/run_all_unittests.cc b/tests/unittests/run_all_unittests.cc index 7c1f6ee2f..4753debf6 100644 --- a/tests/unittests/run_all_unittests.cc +++ b/tests/unittests/run_all_unittests.cc @@ -5,6 +5,7 @@ #include "include/cef_app.h" #include "include/cef_task.h" #include "tests/cefclient/client_app.h" +#include "tests/cefclient/util.h" #include "tests/unittests/test_handler.h" #include "tests/unittests/test_suite.h" #include "base/bind.h" @@ -58,6 +59,15 @@ void RunTests(CefTestThread* thread) { int main(int argc, char* argv[]) { +#if defined(OS_LINUX) + // Create a copy of |argv| on Linux because Chromium mangles the value + // internally (see issue #620). + ScopedArgArray scoped_arg_array(argc, argv); + char** argv_copy = scoped_arg_array.array(); +#else + char** argv_copy = argv; +#endif + #if defined(OS_WIN) CefMainArgs main_args(::GetModuleHandle(NULL)); #else @@ -80,7 +90,7 @@ int main(int argc, char* argv[]) { return exit_code; // Initialize the CommandLine object. - CefTestSuite::InitCommandLine(argc, argv); + CefTestSuite::InitCommandLine(argc, argv_copy); CefSettings settings; CefTestSuite::GetSettings(settings); @@ -94,8 +104,8 @@ int main(int argc, char* argv[]) { // Initialize CEF. CefInitialize(main_args, settings, app, windows_sandbox_info); - // Create the test suite object. - CefTestSuite test_suite(argc, argv); + // Create the test suite object. TestSuite will modify |argv_copy|. + CefTestSuite test_suite(argc, argv_copy); int retval; @@ -133,4 +143,4 @@ int main(int argc, char* argv[]) { #endif return retval; -} +} \ No newline at end of file