mock_nacl_gdb.cc revision 2a99a7e74a7f215066514fe81d2bfa6639d9eddd
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include <cstdio>
6#include <cstring>
7
8#include "base/command_line.h"
9#include "base/environment.h"
10#include "base/file_util.h"
11#include "base/logging.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/process_util.h"
14
15static const char kArgs[] = "--args";
16static const char kEvalCommand[] = "--eval-command";
17static const char kCommand[] = "--command";
18static const char kNaClIrt[] = "nacl-irt ";
19static const char kPass[] = "PASS";
20static const char kDump[] = "dump binary value ";
21static const char kAttach[] = "attach ";
22
23// Send message to child nacl_helper
24void SendMessage(const char* arg) {
25  const char* file_end = strchr(arg, ' ');
26  CHECK(file_end);
27  char buf = '\0';
28  file_util::WriteFile(
29      base::FilePath(base::FilePath::StringType(arg, file_end)), &buf, 1);
30}
31
32int main(int argc, char** argv) {
33  scoped_ptr<base::Environment> env(base::Environment::Create());
34  std::string mock_nacl_gdb_file;
35  env->GetVar("MOCK_NACL_GDB", &mock_nacl_gdb_file);
36  file_util::WriteFile(base::FilePath::FromUTF8Unsafe(mock_nacl_gdb_file),
37                       kPass, strlen(kPass));
38  CHECK_GE(argc, 3);
39  // First argument should be --eval-command.
40  CHECK_EQ(strcmp(argv[1], kEvalCommand), 0);
41  // Second argument should start with nacl-irt.
42  CHECK_GE(strlen(argv[2]), strlen(kNaClIrt));
43  CHECK_EQ(strncmp(argv[2], kNaClIrt, strlen(kNaClIrt)), 0);
44  char* irt_file_name = &argv[2][strlen(kNaClIrt)];
45  FILE* irt_file = fopen(irt_file_name, "r");
46  // nacl-irt parameter must be a file name.
47  PCHECK(irt_file);
48  fclose(irt_file);
49  int i = 3;
50  bool has_attach_cmd = false;
51  char* message_pipe = NULL;
52  // Skip additional --eval-command parameters.
53  while (i < argc) {
54    if (strcmp(argv[i], kArgs) == 0) {
55      i++;
56      break;
57    }
58    if (strcmp(argv[i], kEvalCommand) == 0) {
59      i += 2;
60      // Command line shouldn't end with --eval-command switch without value.
61      CHECK_LE(i, argc);
62      if (strncmp(argv[i - 1], kDump, sizeof(kDump) - 1) == 0) {
63        message_pipe = argv[i - 1] + sizeof(kDump) - 1;
64      } else if (strncmp(argv[i - 1], kAttach, sizeof(kAttach) - 1) == 0) {
65        has_attach_cmd = true;
66      }
67      continue;
68    }
69    if (strcmp(argv[i], kCommand) == 0) {
70      // Command line shouldn't end with --command switch without value.
71      i += 2;
72      CHECK_LE(i, argc);
73      std::string nacl_gdb_script(argv[i - 1]);
74      file_util::WriteFile(base::FilePath::FromUTF8Unsafe(nacl_gdb_script),
75                           kPass, strlen(kPass));
76      continue;
77    }
78    // Unknown argument.
79    NOTREACHED() << "Invalid argument " << argv[i];
80  }
81  if (has_attach_cmd) {
82    CHECK_EQ(i, argc);
83    CHECK(message_pipe);
84    // Test passed, so we can let NaCl launching to continue.
85    SendMessage(message_pipe);
86    return 0;
87  }
88  // --args switch must be present.
89  CHECK_LT(i, argc);
90
91  CommandLine::StringVector arguments;
92  for (; i < argc; i++) {
93    arguments.push_back(
94        CommandLine::StringType(argv[i], argv[i] + strlen(argv[i])));
95  }
96  CommandLine cmd_line(arguments);
97  // Process must be launched successfully.
98  PCHECK(base::LaunchProcess(cmd_line, base::LaunchOptions(), NULL));
99  return 0;
100}
101