Commit 603e1f39 authored by eroman@chromium.org's avatar eroman@chromium.org

Don't pass class types across EXE/DLL boundaries for SetCommandLine() and SetExperimentList().

BUG=128541

Review URL: https://chromiumcodereview.appspot.com/10411059

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@138353 0039d316-1c4b-4281-b951-d872f2087c98
parent 1a99c5a4
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include "chrome/common/child_process_logging.h" #include "chrome/common/child_process_logging.h"
extern "C" void __declspec(dllexport) __cdecl SetExperimentList( extern "C" void __declspec(dllexport) __cdecl SetExperimentList(
const std::vector<string16>& experiment_strings) { const wchar_t** experiment_strings, size_t experiment_strings_size) {
// Make sure we were initialized before we start writing data // Make sure we were initialized before we start writing data
if (breakpad_win::g_experiment_chunks_offset == 0) if (breakpad_win::g_experiment_chunks_offset == 0)
return; return;
...@@ -21,11 +21,11 @@ extern "C" void __declspec(dllexport) __cdecl SetExperimentList( ...@@ -21,11 +21,11 @@ extern "C" void __declspec(dllexport) __cdecl SetExperimentList(
size_t num_chunks = 0; size_t num_chunks = 0;
size_t current_experiment = 0; size_t current_experiment = 0;
string16 current_chunk(google_breakpad::CustomInfoEntry::kValueMaxLength, 0); string16 current_chunk(google_breakpad::CustomInfoEntry::kValueMaxLength, 0);
while (current_experiment < experiment_strings.size() && while (current_experiment < experiment_strings_size &&
num_chunks < kMaxReportedExperimentChunks) { num_chunks < kMaxReportedExperimentChunks) {
// Check if we have enough room to add another experiment to the current // Check if we have enough room to add another experiment to the current
// chunk string. If not, we commit the current chunk string and start over. // chunk string. If not, we commit the current chunk string and start over.
if (current_chunk.size() + experiment_strings[current_experiment].size() > if (current_chunk.size() + wcslen(experiment_strings[current_experiment]) >
google_breakpad::CustomInfoEntry::kValueMaxLength) { google_breakpad::CustomInfoEntry::kValueMaxLength) {
base::wcslcpy( base::wcslcpy(
(*breakpad_win::g_custom_entries)[ (*breakpad_win::g_custom_entries)[
...@@ -58,14 +58,17 @@ extern "C" void __declspec(dllexport) __cdecl SetExperimentList( ...@@ -58,14 +58,17 @@ extern "C" void __declspec(dllexport) __cdecl SetExperimentList(
base::wcslcpy( base::wcslcpy(
(*breakpad_win::g_custom_entries)[ (*breakpad_win::g_custom_entries)[
breakpad_win::g_num_of_experiments_offset].value, breakpad_win::g_num_of_experiments_offset].value,
base::StringPrintf(L"%d", experiment_strings.size()).c_str(), base::StringPrintf(
L"%d", static_cast<int>(experiment_strings_size)).c_str(),
google_breakpad::CustomInfoEntry::kValueMaxLength); google_breakpad::CustomInfoEntry::kValueMaxLength);
} }
namespace testing { namespace testing {
void SetExperimentList(const std::vector<string16>& experiment_strings) { void SetExperimentList(const std::vector<string16>& experiment_strings) {
::SetExperimentList(experiment_strings); std::vector<const wchar_t*> cstrings;
StringVectorToCStringVector(experiment_strings, &cstrings);
::SetExperimentList(&cstrings[0], cstrings.size());
} }
} // namespace testing } // namespace testing
...@@ -152,31 +152,29 @@ bool IsBoringCommandLineSwitch(const std::wstring& flag) { ...@@ -152,31 +152,29 @@ bool IsBoringCommandLineSwitch(const std::wstring& flag) {
} }
extern "C" void __declspec(dllexport) __cdecl SetCommandLine( extern "C" void __declspec(dllexport) __cdecl SetCommandLine(
const CommandLine* command_line) { const wchar_t** argv, size_t argc) {
if (!g_custom_entries) if (!g_custom_entries)
return; return;
const CommandLine::StringVector& argv = command_line->argv();
// Copy up to the kMaxSwitches arguments into the custom entries array. Skip // Copy up to the kMaxSwitches arguments into the custom entries array. Skip
// past the first argument, as it is just the executable path. // past the first argument, as it is just the executable path.
size_t argv_i = 1; size_t argv_i = 1;
size_t num_added = 0; size_t num_added = 0;
for (; argv_i < argv.size() && num_added < kMaxSwitches; ++argv_i) { for (; argv_i < argc && num_added < kMaxSwitches; ++argv_i) {
// Don't bother including boring command line switches in crash reports. // Don't bother including boring command line switches in crash reports.
if (IsBoringCommandLineSwitch(argv[argv_i])) if (IsBoringCommandLineSwitch(argv[argv_i]))
continue; continue;
base::wcslcpy((*g_custom_entries)[g_switches_offset + num_added].value, base::wcslcpy((*g_custom_entries)[g_switches_offset + num_added].value,
argv[argv_i].c_str(), argv[argv_i],
google_breakpad::CustomInfoEntry::kValueMaxLength); google_breakpad::CustomInfoEntry::kValueMaxLength);
num_added++; num_added++;
} }
// Make note of the total number of switches. This is useful in case we have // Make note of the total number of switches. This is useful in case we have
// truncated at kMaxSwitches, to see how many were unaccounted for. // truncated at kMaxSwitches, to see how many were unaccounted for.
SetIntegerValue(g_num_switches_offset, static_cast<int>(argv.size()) - 1); SetIntegerValue(g_num_switches_offset, static_cast<int>(argc) - 1);
} }
// Appends the plugin path to |g_custom_entries|. // Appends the plugin path to |g_custom_entries|.
...@@ -319,7 +317,10 @@ google_breakpad::CustomClientInfo* GetCustomInfo(const std::wstring& exe_path, ...@@ -319,7 +317,10 @@ google_breakpad::CustomClientInfo* GetCustomInfo(const std::wstring& exe_path,
// Fill in the command line arguments using CommandLine::ForCurrentProcess(). // Fill in the command line arguments using CommandLine::ForCurrentProcess().
// The browser process may call SetCommandLine() again later on with a command // The browser process may call SetCommandLine() again later on with a command
// line that has been augmented with the about:flags experiments. // line that has been augmented with the about:flags experiments.
SetCommandLine(CommandLine::ForCurrentProcess()); std::vector<const wchar_t*> switches;
StringVectorToCStringVector(
CommandLine::ForCurrentProcess()->argv(), &switches);
SetCommandLine(&switches[0], switches.size());
if (type == L"renderer" || type == L"plugin" || type == L"gpu-process") { if (type == L"renderer" || type == L"plugin" || type == L"gpu-process") {
g_num_of_views_offset = g_custom_entries->size(); g_num_of_views_offset = g_custom_entries->size();
...@@ -823,3 +824,11 @@ void InitCrashReporter() { ...@@ -823,3 +824,11 @@ void InitCrashReporter() {
void InitDefaultCrashCallback(LPTOP_LEVEL_EXCEPTION_FILTER filter) { void InitDefaultCrashCallback(LPTOP_LEVEL_EXCEPTION_FILTER filter) {
previous_filter = SetUnhandledExceptionFilter(filter); previous_filter = SetUnhandledExceptionFilter(filter);
} }
void StringVectorToCStringVector(const std::vector<std::wstring>& wstrings,
std::vector<const wchar_t*>* cstrings) {
cstrings->clear();
cstrings->reserve(wstrings.size());
for (size_t i = 0; i < wstrings.size(); ++i)
cstrings->push_back(wstrings[i].c_str());
}
\ No newline at end of file
...@@ -42,6 +42,12 @@ void InitDefaultCrashCallback(LPTOP_LEVEL_EXCEPTION_FILTER filter); ...@@ -42,6 +42,12 @@ void InitDefaultCrashCallback(LPTOP_LEVEL_EXCEPTION_FILTER filter);
// a dialog asking for permission to continue execution or to exit now. // a dialog asking for permission to continue execution or to exit now.
bool ShowRestartDialogIfCrashed(bool* exit_now); bool ShowRestartDialogIfCrashed(bool* exit_now);
// Helper to convert a vector of wstrings to corresponding vector of cstrings.
// Note that |cstrings| will reference memory owned by |wstrings|. Consequently
// |wstrings| must outlive |cstrings|, and |wstrings| should not be mutated.
void StringVectorToCStringVector(const std::vector<std::wstring>& wstrings,
std::vector<const wchar_t*>* cstrings);
namespace testing { namespace testing {
// Testing entry point for calling a function from the unnamed namespace. // Testing entry point for calling a function from the unnamed namespace.
......
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
#include "googleurl/src/gurl.h" #include "googleurl/src/gurl.h"
namespace child_process_logging { namespace child_process_logging {
namespace {
// exported in breakpad_win.cc: void __declspec(dllexport) __cdecl SetActiveURL. // exported in breakpad_win.cc: void __declspec(dllexport) __cdecl SetActiveURL.
typedef void (__cdecl *MainSetActiveURL)(const wchar_t*); typedef void (__cdecl *MainSetActiveURL)(const wchar_t*);
...@@ -46,11 +49,22 @@ typedef void (__cdecl *MainSetNumberOfViews)(int); ...@@ -46,11 +49,22 @@ typedef void (__cdecl *MainSetNumberOfViews)(int);
// exported in breakpad_win.cc: // exported in breakpad_win.cc:
// void __declspec(dllexport) __cdecl SetCommandLine // void __declspec(dllexport) __cdecl SetCommandLine
typedef void (__cdecl *MainSetCommandLine)(const CommandLine*); typedef void (__cdecl *MainSetCommandLine)(const wchar_t**, size_t);
// exported in breakpad_field_trial_win.cc: // exported in breakpad_field_trial_win.cc:
// void __declspec(dllexport) __cdecl SetExperimentList // void __declspec(dllexport) __cdecl SetExperimentList
typedef void (__cdecl *MainSetExperimentList)(const std::vector<string16>&); typedef void (__cdecl *MainSetExperimentList)(const wchar_t**, size_t);
// Copied from breakpad_win.cc.
void StringVectorToCStringVector(const std::vector<std::wstring>& wstrings,
std::vector<const wchar_t*>* cstrings) {
cstrings->clear();
cstrings->reserve(wstrings.size());
for (size_t i = 0; i < wstrings.size(); ++i)
cstrings->push_back(wstrings[i].c_str());
}
} // namespace
void SetActiveURL(const GURL& url) { void SetActiveURL(const GURL& url) {
static MainSetActiveURL set_active_url = NULL; static MainSetActiveURL set_active_url = NULL;
...@@ -189,7 +203,10 @@ void SetCommandLine(const CommandLine* command_line) { ...@@ -189,7 +203,10 @@ void SetCommandLine(const CommandLine* command_line) {
if (!set_command_line) if (!set_command_line)
return; return;
} }
(set_command_line)(command_line);
std::vector<const wchar_t*> cstrings;
StringVectorToCStringVector(command_line->argv(), &cstrings);
(set_command_line)(&cstrings[0], cstrings.size());
} }
void SetExperimentList(const std::vector<string16>& state) { void SetExperimentList(const std::vector<string16>& state) {
...@@ -204,7 +221,10 @@ void SetExperimentList(const std::vector<string16>& state) { ...@@ -204,7 +221,10 @@ void SetExperimentList(const std::vector<string16>& state) {
if (!set_experiment_list) if (!set_experiment_list)
return; return;
} }
(set_experiment_list)(state);
std::vector<const wchar_t*> cstrings;
StringVectorToCStringVector(state, &cstrings);
(set_experiment_list)(&cstrings[0], cstrings.size());
} }
void SetNumberOfViews(int number_of_views) { void SetNumberOfViews(int number_of_views) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment