mock_nacl_gdb.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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(FilePath(FilePath::StringType(arg, file_end)), &buf, 1);
29}
30
31int main(int argc, char** argv) {
32  scoped_ptr<base::Environment> env(base::Environment::Create());
33  std::string mock_nacl_gdb_file;
34  env->GetVar("MOCK_NACL_GDB", &mock_nacl_gdb_file);
35  file_util::WriteFile(FilePath::FromUTF8Unsafe(mock_nacl_gdb_file),
36                       kPass, strlen(kPass));
37  CHECK_GE(argc, 3);
38  // First argument should be --eval-command.
39  CHECK_EQ(strcmp(argv[1], kEvalCommand), 0);
40  // Second argument should start with nacl-irt.
41  CHECK_GE(strlen(argv[2]), strlen(kNaClIrt));
42  CHECK_EQ(strncmp(argv[2], kNaClIrt, strlen(kNaClIrt)), 0);
43  char* irt_file_name = &argv[2][strlen(kNaClIrt)];
44  FILE* irt_file = fopen(irt_file_name, "r");
45  // nacl-irt parameter must be a file name.
46  PCHECK(irt_file);
47  fclose(irt_file);
48  int i = 3;
49  bool has_attach_cmd = false;
50  char* message_pipe = NULL;
51  // Skip additional --eval-command parameters.
52  while (i < argc) {
53    if (strcmp(argv[i], kArgs) == 0) {
54      i++;
55      break;
56    }
57    if (strcmp(argv[i], kEvalCommand) == 0) {
58      i += 2;
59      // Command line shouldn't end with --eval-command switch without value.
60      CHECK_LE(i, argc);
61      if (strncmp(argv[i - 1], kDump, sizeof(kDump) - 1) == 0) {
62        message_pipe = argv[i - 1] + sizeof(kDump) - 1;
63      } else if (strncmp(argv[i - 1], kAttach, sizeof(kAttach) - 1) == 0) {
64        has_attach_cmd = true;
65      }
66      continue;
67    }
68    if (strcmp(argv[i], kCommand) == 0) {
69      // Command line shouldn't end with --command switch without value.
70      i += 2;
71      CHECK_LE(i, argc);
72      std::string nacl_gdb_script(argv[i - 1]);
73      file_util::WriteFile(FilePath::FromUTF8Unsafe(nacl_gdb_script),
74                           kPass, strlen(kPass));
75      continue;
76    }
77    // Unknown argument.
78    NOTREACHED() << "Invalid argument " << argv[i];
79  }
80  if (has_attach_cmd) {
81    CHECK_EQ(i, argc);
82    CHECK(message_pipe);
83    // Test passed, so we can let NaCl launching to continue.
84    SendMessage(message_pipe);
85    return 0;
86  }
87  // --args switch must be present.
88  CHECK_LT(i, argc);
89
90  CommandLine::StringVector arguments;
91  for (; i < argc; i++) {
92    arguments.push_back(
93        CommandLine::StringType(argv[i], argv[i] + strlen(argv[i])));
94  }
95  CommandLine cmd_line(arguments);
96  // Process must be launched successfully.
97  PCHECK(base::LaunchProcess(cmd_line, base::LaunchOptions(), NULL));
98  return 0;
99}
100