diff options
author | halyavin@google.com <halyavin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-11 12:37:46 +0000 |
---|---|---|
committer | halyavin@google.com <halyavin@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-03-11 12:37:46 +0000 |
commit | 31a665e72dd82aa93fc05bc402395f0ab579a26b (patch) | |
tree | 2a0a5212e0e01db54e35e27f65149972841b9018 | |
parent | 50da420e19f5039a441126440273cc36f132e1b6 (diff) | |
download | chromium_src-31a665e72dd82aa93fc05bc402395f0ab579a26b.zip chromium_src-31a665e72dd82aa93fc05bc402395f0ab579a26b.tar.gz chromium_src-31a665e72dd82aa93fc05bc402395f0ab579a26b.tar.bz2 |
Adds new flag "--nacl-gdb". If this flag is set, NaCl loaders will be launched under nacl-gdb on Windows.
BUG= 117010
TEST= none
Review URL: http://codereview.chromium.org/9585007
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@126069 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/app/generated_resources.grd | 6 | ||||
-rw-r--r-- | chrome/browser/about_flags.cc | 7 | ||||
-rw-r--r-- | chrome/browser/nacl_host/nacl_process_host.cc | 105 | ||||
-rw-r--r-- | chrome/browser/nacl_host/nacl_process_host.h | 4 | ||||
-rw-r--r-- | chrome/common/chrome_switches.cc | 5 | ||||
-rw-r--r-- | chrome/common/chrome_switches.h | 1 | ||||
-rw-r--r-- | chrome/tools/chromeactions.txt | 1 |
7 files changed, 114 insertions, 15 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index a6367a0..7519607 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -4760,6 +4760,12 @@ Keep your key file in a safe place. You will need it to create new versions of y <message name="IDS_FLAGS_ENABLE_NACL_EXCEPTION_HANDLING_DESCRIPTION" desc="Description of the 'Enable Native Client hardware exception handling' lab."> Enable support for Native Client hardware exception handling. </message> + <message name="IDS_FLAGS_NACL_GDB_NAME" desc="Name of the 'Debug Native Client applications at startup' lab"> + Debug Native Client applications at startup. + </message> + <message name="IDS_FLAGS_NACL_GDB_DESCRIPTION" desc="Description of the 'Debug Native Client applications at startup' lab."> + Set path to nacl-gdb debugger. It will be attached to NaCl applications at startup. + </message> <message name="IDS_FLAGS_DISABLE_SHORTCUTS_PROVIDER" desc="Name of the 'Disable better ranking of previously selected shortcuts in omnibox' lab."> Disable 'shortcuts' in the omnibox. </message> diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index c4cfb94..7672b4e 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc @@ -249,6 +249,13 @@ const Experiment kExperiments[] = { SINGLE_VALUE_TYPE(switches::kEnableNaClExceptionHandling) }, { + "nacl-gdb", // FLAGS:RECORD_UMA + IDS_FLAGS_NACL_GDB_NAME, + IDS_FLAGS_NACL_GDB_DESCRIPTION, + kOsWin, + SINGLE_VALUE_TYPE(switches::kNaClGdb) + }, + { "extension-apis", // FLAGS:RECORD_UMA IDS_FLAGS_EXPERIMENTAL_EXTENSION_APIS_NAME, IDS_FLAGS_EXPERIMENTAL_EXTENSION_APIS_DESCRIPTION, diff --git a/chrome/browser/nacl_host/nacl_process_host.cc b/chrome/browser/nacl_host/nacl_process_host.cc index 12efb02e..8b585a5 100644 --- a/chrome/browser/nacl_host/nacl_process_host.cc +++ b/chrome/browser/nacl_host/nacl_process_host.cc @@ -15,6 +15,7 @@ #include "base/utf_string_conversions.h" #include "base/win/windows_version.h" #include "build/build_config.h" +#include "chrome/common/chrome_constants.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/logging_chrome.h" @@ -187,20 +188,29 @@ class NaClBrowser { // Make sure the IRT gets opened and follow up with the reply when it's ready. bool MakeIrtAvailable(const base::Closure& reply); + // Path to IRT. Available even before IRT is loaded. + const FilePath& GetIrtFilePath(); + private: base::PlatformFile irt_platform_file_; + FilePath irt_filepath_; + friend struct DefaultSingletonTraits<NaClBrowser>; NaClBrowser() - : irt_platform_file_(base::kInvalidPlatformFileValue) - {} + : irt_platform_file_(base::kInvalidPlatformFileValue), + irt_filepath_() { + InitIrtFilePath(); + } ~NaClBrowser() { if (irt_platform_file_ != base::kInvalidPlatformFileValue) base::ClosePlatformFile(irt_platform_file_); } + void InitIrtFilePath(); + void OpenIrtLibraryFile(); static void DoOpenIrtLibraryFile() { @@ -354,6 +364,22 @@ bool NaClProcessHost::Launch( return true; } +scoped_ptr<CommandLine> NaClProcessHost::LaunchWithNaClGdb(FilePath nacl_gdb, + CommandLine* line) { + CommandLine* cmd_line = new CommandLine(nacl_gdb); + // We can't use PrependWrapper because our parameters contain spaces. + cmd_line->AppendArg("--eval-command"); + const FilePath::StringType& irt_path = + NaClBrowser::GetInstance()->GetIrtFilePath().value(); + cmd_line->AppendArgNative(FILE_PATH_LITERAL("nacl-irt ") + irt_path); + cmd_line->AppendArg("--args"); + const CommandLine::StringVector& argv = line->argv(); + for (size_t i = 0; i < argv.size(); i++) { + cmd_line->AppendArgNative(argv[i]); + } + return scoped_ptr<CommandLine>(cmd_line); +} + bool NaClProcessHost::LaunchSelLdr() { std::string channel_id = process_->GetHost()->CreateChannel(); if (channel_id.empty()) @@ -386,6 +412,16 @@ bool NaClProcessHost::LaunchSelLdr() { if (exe_path.empty()) return false; +#if defined(OS_WIN) + // On Windows 64-bit NaCl loader is called nacl64.exe instead of chrome.exe + if (RunningOnWOW64()) { + FilePath module_path; + if (!PathService::Get(base::FILE_MODULE, &module_path)) + return false; + exe_path = module_path.DirName().Append(chrome::kNaClAppName); + } +#endif + scoped_ptr<CommandLine> cmd_line(new CommandLine(exe_path)); nacl::CopyNaClCommandLineArguments(cmd_line.get()); @@ -398,6 +434,23 @@ bool NaClProcessHost::LaunchSelLdr() { if (!nacl_loader_prefix.empty()) cmd_line->PrependWrapper(nacl_loader_prefix); + FilePath nacl_gdb = CommandLine::ForCurrentProcess()->GetSwitchValuePath( + switches::kNaClGdb); + if (!nacl_gdb.empty()) { + cmd_line->AppendSwitch(switches::kNoSandbox); + scoped_ptr<CommandLine> gdb_cmd_line( + LaunchWithNaClGdb(nacl_gdb, cmd_line.get())); + // We can't use process_->Launch() because OnProcessLaunched will be called + // with process_->GetData().handle filled by handle of gdb process. This + // handle will be used to duplicate handles for NaCl process and as + // a result NaCl process will not be able to use them. + // + // So we don't fill process_->GetData().handle and wait for + // OnChannelConnected to get handle of NaCl process from its pid. Then we + // call OnProcessLaunched. + return base::LaunchProcess(*gdb_cmd_line, base::LaunchOptions(), NULL); + } + // On Windows we might need to start the broker process to launch a new loader #if defined(OS_WIN) if (RunningOnWOW64()) { @@ -457,15 +510,7 @@ const FilePath::StringType NaClIrtName() { } // namespace -// This only ever runs on the BrowserThread::FILE thread. -// If multiple tasks are posted, the later ones are no-ops. -void NaClBrowser::OpenIrtLibraryFile() { - if (irt_platform_file_ != base::kInvalidPlatformFileValue) - // We've already run. - return; - - FilePath irt_filepath; - +void NaClBrowser::InitIrtFilePath() { // Allow the IRT library to be overridden via an environment // variable. This allows the NaCl/Chromium integration bot to // specify a newly-built IRT rather than using a prebuilt one @@ -475,7 +520,7 @@ void NaClBrowser::OpenIrtLibraryFile() { if (irt_path_var != NULL) { FilePath::StringType path_string( irt_path_var, const_cast<const char*>(strchr(irt_path_var, '\0'))); - irt_filepath = FilePath(path_string); + irt_filepath_ = FilePath(path_string); } else { FilePath plugin_dir; if (!PathService::Get(chrome::DIR_INTERNAL_PLUGINS, &plugin_dir)) { @@ -483,18 +528,30 @@ void NaClBrowser::OpenIrtLibraryFile() { return; } - irt_filepath = plugin_dir.Append(NaClIrtName()); + irt_filepath_ = plugin_dir.Append(NaClIrtName()); } +} + +const FilePath& NaClBrowser::GetIrtFilePath() { + return irt_filepath_; +} + +// This only ever runs on the BrowserThread::FILE thread. +// If multiple tasks are posted, the later ones are no-ops. +void NaClBrowser::OpenIrtLibraryFile() { + if (irt_platform_file_ != base::kInvalidPlatformFileValue) + // We've already run. + return; base::PlatformFileError error_code; - irt_platform_file_ = base::CreatePlatformFile(irt_filepath, + irt_platform_file_ = base::CreatePlatformFile(irt_filepath_, base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ, NULL, &error_code); if (error_code != base::PLATFORM_FILE_OK) { LOG(ERROR) << "Failed to open NaCl IRT file \"" - << irt_filepath.LossyDisplayName() + << irt_filepath_.LossyDisplayName() << "\": " << error_code; } } @@ -533,6 +590,24 @@ bool NaClProcessHost::IsHardwareExceptionHandlingEnabled() { } void NaClProcessHost::OnChannelConnected(int32 peer_pid) { + // Set process handle, if it was not set previously. + // This is needed when NaCl process is launched with nacl-gdb. + if (process_->GetData().handle == base::kNullProcessHandle) { + base::ProcessHandle process; + DCHECK(!CommandLine::ForCurrentProcess()->GetSwitchValuePath( + switches::kNaClGdb).empty()); + if (base::OpenProcessHandleWithAccess( + peer_pid, + base::kProcessAccessDuplicateHandle | + base::kProcessAccessQueryLimitedInfomation | + base::kProcessAccessWaitForTermination, + &process)) { + process_->SetHandle(process); + OnProcessLaunched(); + } else { + LOG(ERROR) << "Failed to get process handle"; + } + } if (!IsHardwareExceptionHandlingEnabled()) { return; } diff --git a/chrome/browser/nacl_host/nacl_process_host.h b/chrome/browser/nacl_host/nacl_process_host.h index 5e5f819..5b4a59e 100644 --- a/chrome/browser/nacl_host/nacl_process_host.h +++ b/chrome/browser/nacl_host/nacl_process_host.h @@ -17,6 +17,7 @@ #include "content/public/browser/browser_child_process_host_delegate.h" class ChromeRenderMessageFilter; +class CommandLine; namespace content { class BrowserChildProcessHost; @@ -55,6 +56,9 @@ class NaClProcessHost : public content::BrowserChildProcessHostDelegate { // depends on chrome.gyp (circular dependency). struct NaClInternal; + // Create command line for launching loader under nacl-gdb. + scoped_ptr<CommandLine> LaunchWithNaClGdb(FilePath nacl_gdb, + CommandLine* line); bool LaunchSelLdr(); // BrowserChildProcessHostDelegate implementation: diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index 77ea4fb..e999115 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -798,6 +798,11 @@ const char kMetricsRecordingOnly[] = "metrics-recording-only"; // Enables multiprofile Chrome. const char kMultiProfiles[] = "multi-profiles"; +// Native Client GDB debugger for loader. It needs switches calculated +// at run time in order to work correctly. That's why NaClLoadCmdPrefix +// flag can't be used. +const char kNaClGdb[] = "nacl-gdb"; + // On POSIX only: the contents of this flag are prepended to the nacl-loader // command line. Useful values might be "valgrind" or "xterm -e gdb --args". const char kNaClLoaderCmdPrefix[] = "nacl-loader-cmd-prefix"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index a221d2f..9c8e741 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -218,6 +218,7 @@ extern const char kMemoryWidget[]; extern const char kMessageLoopHistogrammer[]; extern const char kMetricsRecordingOnly[]; extern const char kMultiProfiles[]; +extern const char kNaClGdb[]; extern const char kNaClLoaderCmdPrefix[]; extern const char kNetLogLevel[]; extern const char kNoDefaultBrowserCheck[]; diff --git a/chrome/tools/chromeactions.txt b/chrome/tools/chromeactions.txt index b1d72d8..3fb362f 100644 --- a/chrome/tools/chromeactions.txt +++ b/chrome/tools/chromeactions.txt @@ -24,6 +24,7 @@ 0x67b7031bb00a6917 AboutFlags_instant-type 0x681dbf08b11af420 AboutFlags_match-preview 0x0156f26c1be32122 AboutFlags_my-special-feature +0x94c46ee32cd0fd19 AboutFlags_nacl-gdb 0xb41d9c886871e31a AboutFlags_page-prerender 0x735ca25b198de8ab AboutFlags_prerender-from-omnibox 0xb33861525ba727a4 AboutFlags_print-preview |