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

Side by Side Diff: chrome/nacl/nacl_helper_linux.cc

Issue 8491060: Make nacl_helper easily debuggable (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // A mini-zygote specifically for Native Client. 5 // A mini-zygote specifically for Native Client.
6 6
7 #include "chrome/common/nacl_helper_linux.h" 7 #include "chrome/common/nacl_helper_linux.h"
8 8
9 #include <errno.h> 9 #include <errno.h>
10 #include <link.h>
10 #include <stdlib.h> 11 #include <stdlib.h>
11 #include <sys/socket.h> 12 #include <sys/socket.h>
12 #include <sys/types.h> 13 #include <sys/types.h>
13 14
14 #include <string> 15 #include <string>
15 #include <vector> 16 #include <vector>
16 17
17 #include "base/at_exit.h" 18 #include "base/at_exit.h"
18 #include "base/command_line.h" 19 #include "base/command_line.h"
19 #include "base/eintr_wrapper.h" 20 #include "base/eintr_wrapper.h"
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
111 if (HANDLE_EINTR(send(kNaClZygoteDescriptor, 112 if (HANDLE_EINTR(send(kNaClZygoteDescriptor,
112 &childpid, sizeof(childpid), MSG_EOR)) 113 &childpid, sizeof(childpid), MSG_EOR))
113 != sizeof(childpid)) { 114 != sizeof(childpid)) {
114 LOG(ERROR) << "*** send() to zygote failed"; 115 LOG(ERROR) << "*** send() to zygote failed";
115 } 116 }
116 } 117 }
117 118
118 } // namespace 119 } // namespace
119 120
120 static const char kNaClHelperAtZero[] = "at-zero"; 121 static const char kNaClHelperAtZero[] = "at-zero";
122 static const char kNaClHelperRDebug[] = "r_debug";
123
124 /*
125 * Since we were started by the bootstrap program rather than in the
126 * usual way, the debugger cannot figure out where our executable
127 * or the dynamic linker or the shared libraries are in memory,
128 * so it won't find any symbols. But we can fake it out to find us.
129 *
130 * The zygote passes --r_debug=0xXXXXXXXXXXXXXXXX. The bootstrap
131 * program replaces the Xs with the address of its _r_debug
132 * structure. The debugger will look for that symbol by name to
133 * discover the addresses of key dynamic linker data structures.
134 * Since all it knows about is the original main executable, which
135 * is the bootstrap program, it finds the symbol defined there. The
136 * dynamic linker's structure is somewhere else, but it is filled in
137 * after initialization. The parts that really matter to the
138 * debugger never change. So we just copy the contents of the
139 * dynamic linker's structure into the address provided by the option.
140 * Hereafter, if someone attaches a debugger (or examines a core dump),
141 * the debugger will find all the symbols in the normal way.
142 */
143 static void check_r_debug(char *argv0) {
144 std::string r_debug_switch_value =
145 CommandLine::ForCurrentProcess()->GetSwitchValueASCII(kNaClHelperRDebug);
146 if (!r_debug_switch_value.empty()) {
147 char *endp = NULL;
148 uintptr_t r_debug_addr = strtoul(r_debug_switch_value.c_str(), &endp, 0);
149 if (r_debug_addr != 0 && *endp == '\0') {
150 struct r_debug *bootstrap_r_debug = (struct r_debug *) r_debug_addr;
151 *bootstrap_r_debug = _r_debug;
eaeltsin 2011/11/12 01:35:23 Neat. A very useful complement would be to introd
eaeltsin 2011/11/12 01:52:19 Related note: if we want to support subsequent inv
Mark Seaborn 2011/11/14 20:15:41 Is the symbol _r_debug part of the public ABI such
152
153 /*
154 * Since the main executable (the bootstrap program) does not
155 * have a dynamic section, the debugger will not skip the
156 * first element of the link_map list as it usually would for
157 * an executable or PIE that was loaded normally. But the
158 * dynamic linker has set l_name for the PIE to "" as is
159 * normal for the main executable. So the debugger doesn't
160 * know which file it is. Fill in the actual file name, which
161 * came in as our argv[0].
162 */
163 struct link_map *l = _r_debug.r_map;
164 if (l->l_name[0] == '\0')
165 l->l_name = argv0;
Mark Seaborn 2011/11/14 20:15:41 I find modifying the dynamic linker's data structu
166 }
167 }
168 }
121 169
122 int main(int argc, char *argv[]) { 170 int main(int argc, char *argv[]) {
123 CommandLine::Init(argc, argv); 171 CommandLine::Init(argc, argv);
124 base::AtExitManager exit_manager; 172 base::AtExitManager exit_manager;
125 base::RandUint64(); // acquire /dev/urandom fd before sandbox is raised 173 base::RandUint64(); // acquire /dev/urandom fd before sandbox is raised
126 std::vector<int> empty; // for SendMsg() calls 174 std::vector<int> empty; // for SendMsg() calls
127 175
176 check_r_debug(argv[0]);
177
128 g_suid_sandbox_active = (NULL != getenv("SBX_D")); 178 g_suid_sandbox_active = (NULL != getenv("SBX_D"));
129 179
130 if (CommandLine::ForCurrentProcess()->HasSwitch(kNaClHelperAtZero)) { 180 if (CommandLine::ForCurrentProcess()->HasSwitch(kNaClHelperAtZero)) {
131 g_nacl_prereserved_sandbox_addr = (void *) (uintptr_t) 0x10000; 181 g_nacl_prereserved_sandbox_addr = (void *) (uintptr_t) 0x10000;
132 } 182 }
133 183
134 // Send the zygote a message to let it know we are ready to help 184 // Send the zygote a message to let it know we are ready to help
135 if (!UnixDomainSocket::SendMsg(kNaClZygoteDescriptor, 185 if (!UnixDomainSocket::SendMsg(kNaClZygoteDescriptor,
136 kNaClHelperStartupAck, 186 kNaClHelperStartupAck,
137 sizeof(kNaClHelperStartupAck), empty)) { 187 sizeof(kNaClHelperStartupAck), empty)) {
(...skipping 27 matching lines...) Expand all
165 } 215 }
166 } 216 }
167 // if fork fails, send PID=-1 to zygote 217 // if fork fails, send PID=-1 to zygote
168 if (!UnixDomainSocket::SendMsg(kNaClZygoteDescriptor, &badpid, 218 if (!UnixDomainSocket::SendMsg(kNaClZygoteDescriptor, &badpid,
169 sizeof(badpid), empty)) { 219 sizeof(badpid), empty)) {
170 LOG(ERROR) << "*** send() to zygote failed"; 220 LOG(ERROR) << "*** send() to zygote failed";
171 } 221 }
172 } 222 }
173 CHECK(false); // This routine must not return 223 CHECK(false); // This routine must not return
174 } 224 }
OLDNEW
« chrome/nacl/nacl_helper_bootstrap_linux.x ('K') | « chrome/nacl/nacl_helper_bootstrap_linux.x ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698