summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhalyavin@google.com <halyavin@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-11 12:37:46 +0000
committerhalyavin@google.com <halyavin@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-11 12:37:46 +0000
commit31a665e72dd82aa93fc05bc402395f0ab579a26b (patch)
tree2a0a5212e0e01db54e35e27f65149972841b9018
parent50da420e19f5039a441126440273cc36f132e1b6 (diff)
downloadchromium_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.grd6
-rw-r--r--chrome/browser/about_flags.cc7
-rw-r--r--chrome/browser/nacl_host/nacl_process_host.cc105
-rw-r--r--chrome/browser/nacl_host/nacl_process_host.h4
-rw-r--r--chrome/common/chrome_switches.cc5
-rw-r--r--chrome/common/chrome_switches.h1
-rw-r--r--chrome/tools/chromeactions.txt1
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