Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4)

Unified Diff: chrome/browser/nacl_host/nacl_process_host.cc

Issue 9950055: Enable --nacl-gdb flag on Linux. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/nacl_host/nacl_process_host.h ('k') | chrome/browser/nacl_host/test/mock_nacl_gdb.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/nacl_host/nacl_process_host.cc
===================================================================
--- chrome/browser/nacl_host/nacl_process_host.cc (revision 130109)
+++ chrome/browser/nacl_host/nacl_process_host.cc (working copy)
@@ -11,8 +11,11 @@
#include "base/command_line.h"
#include "base/memory/mru_cache.h"
#include "base/memory/singleton.h"
+#include "base/message_loop.h"
#include "base/metrics/histogram.h"
#include "base/path_service.h"
+#include "base/string_number_conversions.h"
+#include "base/string_split.h"
#include "base/string_util.h"
#include "base/rand_util.h"
#include "base/stringprintf.h"
@@ -268,6 +271,8 @@
:
#if defined(OS_WIN)
process_launched_by_broker_(false),
+#elif defined(OS_LINUX)
+ wait_for_nacl_gdb_(false),
#endif
reply_msg_(NULL),
internal_(new NaClInternal()),
@@ -408,17 +413,17 @@
delete this;
}
}
-
+#if defined(OS_WIN)
scoped_ptr<CommandLine> NaClProcessHost::LaunchWithNaClGdb(
const FilePath& nacl_gdb,
- CommandLine* line,
- const FilePath& manifest_path) {
+ 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);
+ FilePath manifest_path = GetManifestPath();
if (!manifest_path.empty()) {
cmd_line->AppendArg("--eval-command");
cmd_line->AppendArgNative(FILE_PATH_LITERAL("nacl-manifest ") +
@@ -431,7 +436,102 @@
}
return scoped_ptr<CommandLine>(cmd_line);
}
+#elif defined(OS_LINUX)
+namespace {
+class NaClGdbWatchDelegate : public MessageLoopForIO::Watcher {
+ public:
+ NaClGdbWatchDelegate(int fd_read, int fd_write,
+ const base::Closure& reply)
+ : fd_read_(fd_read),
+ fd_write_(fd_write),
+ reply_(reply) {}
+ ~NaClGdbWatchDelegate() {
+ if (HANDLE_EINTR(close(fd_read_)) != 0)
+ DLOG(ERROR) << "close(fd_read_) failed";
+ if (HANDLE_EINTR(close(fd_write_)) != 0)
+ DLOG(ERROR) << "close(fd_write_) failed";
+ }
+
+ virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE;
+ virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {}
+
+ private:
+ int fd_read_;
+ int fd_write_;
Mark Seaborn 2012/04/04 15:46:13 Please comment here that fd_write_ is not used her
halyavin 2012/04/04 16:08:51 Done.
+ base::Closure reply_;
+};
+
+void NaClGdbWatchDelegate::OnFileCanReadWithoutBlocking(int fd) {
+ char buf;
+ if (HANDLE_EINTR(read(fd_read_, &buf, 1)) != 1 || buf != '\0')
+ LOG(ERROR) << "Failed to sync with nacl-gdb";
+ BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, reply_);
+}
+} // namespace
+
+bool NaClProcessHost::LaunchNaClGdb(base::ProcessId pid) {
+ CommandLine::StringType nacl_gdb =
+ CommandLine::ForCurrentProcess()->GetSwitchValueNative(
+ switches::kNaClGdb);
+ CommandLine::StringVector argv;
+ // We don't support spaces inside arguments in --nacl-gdb switch.
+ base::SplitString(nacl_gdb, static_cast<CommandLine::CharType>(' '), &argv);
+ CommandLine cmd_line(argv);
+ cmd_line.AppendArg("--eval-command");
+ const FilePath::StringType& irt_path =
+ NaClBrowser::GetInstance()->GetIrtFilePath().value();
+ cmd_line.AppendArgNative(FILE_PATH_LITERAL("nacl-irt ") + irt_path);
+ FilePath manifest_path = GetManifestPath();
+ if (!manifest_path.empty()) {
+ cmd_line.AppendArg("--eval-command");
+ cmd_line.AppendArgNative(FILE_PATH_LITERAL("nacl-manifest ") +
+ manifest_path.value());
+ }
+ cmd_line.AppendArg("--eval-command");
+ cmd_line.AppendArg("attach " + base::IntToString(pid));
+ int fds[2];
+ if (pipe(fds) != 0)
+ return false;
+ cmd_line.AppendArg("--eval-command");
+ cmd_line.AppendArg("dump binary value /proc/" +
+ base::IntToString(base::GetCurrentProcId()) +
+ "/fd/" + base::IntToString(fds[1]) + " (char)0");
+ // wait on fds[0]
+ nacl_gdb_watcher_delegate_.reset(
+ new NaClGdbWatchDelegate(
+ fds[0], fds[1],
+ base::Bind(&NaClProcessHost::OnNaClGdbAttached,
+ weak_factory_.GetWeakPtr())));
+ MessageLoopForIO::current()->WatchFileDescriptor(
+ fds[0],
+ true,
+ MessageLoopForIO::WATCH_READ,
+ &nacl_gdb_watcher_,
+ nacl_gdb_watcher_delegate_.get());
+ return base::LaunchProcess(cmd_line, base::LaunchOptions(), NULL);
+}
+
+void NaClProcessHost::OnNaClGdbAttached() {
+ wait_for_nacl_gdb_ = false;
+ nacl_gdb_watcher_.StopWatchingFileDescriptor();
+ nacl_gdb_watcher_delegate_.reset();
+ OnProcessLaunched();
+}
+#endif
+
+FilePath NaClProcessHost::GetManifestPath() {
+ GURL manifest_url = GURL(process_->GetData().name);
+ const Extension* extension = extension_info_map_->extensions()
+ .GetExtensionOrAppByURL(ExtensionURLInfo(manifest_url));
+ if (extension != NULL && manifest_url.SchemeIs(chrome::kExtensionScheme)) {
+ std::string path = manifest_url.path();
+ TrimString(path, "/", &path); // Remove first slash
+ return extension->path().AppendASCII(path);
+ }
+ return FilePath();
+}
+
bool NaClProcessHost::LaunchSelLdr() {
std::string channel_id = process_->GetHost()->CreateChannel();
if (channel_id.empty())
@@ -489,18 +589,10 @@
FilePath nacl_gdb = CommandLine::ForCurrentProcess()->GetSwitchValuePath(
switches::kNaClGdb);
if (!nacl_gdb.empty()) {
- GURL manifest_url = GURL(process_->GetData().name);
- FilePath manifest_path;
- const Extension* extension = extension_info_map_->extensions().
- GetExtensionOrAppByURL(ExtensionURLInfo(manifest_url));
- if (extension != NULL && manifest_url.SchemeIs(chrome::kExtensionScheme)) {
- std::string path = manifest_url.path();
- TrimString(path, "/", &path); // Remove first slash
- manifest_path = extension->path().AppendASCII(path);
- }
+#if defined(OS_WIN)
cmd_line->AppendSwitch(switches::kNoSandbox);
scoped_ptr<CommandLine> gdb_cmd_line(
- LaunchWithNaClGdb(nacl_gdb, cmd_line.get(), manifest_path));
+ 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
@@ -510,6 +602,9 @@
// OnChannelConnected to get handle of NaCl process from its pid. Then we
// call OnProcessLaunched.
return base::LaunchProcess(*gdb_cmd_line, base::LaunchOptions(), NULL);
+#elif defined(OS_LINUX)
+ wait_for_nacl_gdb_ = true;
+#endif
}
// On Windows we might need to start the broker process to launch a new loader
@@ -624,6 +719,17 @@
}
void NaClProcessHost::OnProcessLaunched() {
+#if defined(OS_LINUX)
+ if (wait_for_nacl_gdb_) {
+ if (LaunchNaClGdb(base::GetProcId(process_->GetData().handle))) {
+ // OnProcessLaunched will be called with wait_for_nacl_gdb_ = false once
+ // debugger is attached to the program.
+ return;
+ }
+ LOG(ERROR) << "Failed to launch debugger";
+ // Continue execution without debugger.
+ }
+#endif
NaClBrowser* nacl_browser = NaClBrowser::GetInstance();
if (nacl_browser->IrtAvailable()) {
« no previous file with comments | « chrome/browser/nacl_host/nacl_process_host.h ('k') | chrome/browser/nacl_host/test/mock_nacl_gdb.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698