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

Side by Side Diff: sandbox/linux/seccomp/debug.cc

Issue 997009: Compute and pring the time that it takes to execute system calls. This data... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « sandbox/linux/seccomp/debug.h ('k') | sandbox/linux/seccomp/exit.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 #ifndef NDEBUG 5 #ifndef NDEBUG
6 6
7 #include "debug.h" 7 #include "debug.h"
8 8
9 namespace playground { 9 namespace playground {
10 10
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 for (std::map<int, std::string>::const_iterator iter = 117 for (std::map<int, std::string>::const_iterator iter =
118 syscallNamesMap_.begin(); 118 syscallNamesMap_.begin();
119 iter != syscallNamesMap_.end(); 119 iter != syscallNamesMap_.end();
120 ++iter) { 120 ++iter) {
121 syscallNames_[iter->first] = iter->second.c_str(); 121 syscallNames_[iter->first] = iter->second.c_str();
122 } 122 }
123 } 123 }
124 } 124 }
125 } 125 }
126 126
127 void Debug::message(const char* msg) { 127 bool Debug::enter() {
128 // Increment the recursion level in TLS storage. This allows us to
129 // make system calls from within our debugging functions, without triggering
130 // additional debugging output.
131 //
132 // This function can be called from both the sandboxed process and from the
133 // trusted process. Only the sandboxed process needs to worry about
134 // recursively calling system calls. The trusted process doesn't intercept
135 // system calls and thus doesn't have this problem. It also doesn't have
136 // a TLS. We explicitly set the segment selector to zero, when in the
137 // trusted process, so that we can avoid tracking recursion levels.
138 int level;
139 #if defined(__x86_64__)
140 asm volatile("mov %%gs, %0\n"
141 "test %0, %0\n"
142 "jz 1f\n"
143 "movl %%gs:0x1050-0xD8, %0\n"
144 "incl %%gs:0x1050-0xD8\n"
145 "1:\n"
146 : "=r"(level)
147 :
148 : "memory");
149 #elif defined(__i386__)
150 asm volatile("mov %%fs, %0\n"
151 "test %0, %0\n"
152 "jz 1f\n"
153 "movl %%fs:0x1034-0x54, %0\n"
154 "incl %%fs:0x1034-0x54\n"
155 "1:\n"
156 : "=r"(level)
157 :
158 : "memory");
159 #else
160 #error "Unsupported target platform"
161 #endif
162 return !level;
163 }
164
165 bool Debug::leave() {
166 // Decrement the recursion level in TLS storage. This allows us to
167 // make system calls from within our debugging functions, without triggering
168 // additional debugging output.
169 //
170 // This function can be called from both the sandboxed process and from the
171 // trusted process. Only the sandboxed process needs to worry about
172 // recursively calling system calls. The trusted process doesn't intercept
173 // system calls and thus doesn't have this problem. It also doesn't have
174 // a TLS. We explicitly set the segment selector to zero, when in the
175 // trusted process, so that we can avoid tracking recursion levels.
176 int level;
177 #if defined(__x86_64__)
178 asm volatile("mov %%gs, %0\n"
179 "test %0, %0\n"
180 "jz 1f\n"
181 "decl %%gs:0x1050-0xD8\n"
182 "movl %%gs:0x1050-0xD8, %0\n"
183 "1:\n"
184 : "=r"(level)
185 :
186 : "memory");
187 #elif defined(__i386__)
188 asm volatile("mov %%fs, %0\n"
189 "test %0, %0\n"
190 "jz 1f\n"
191 "decl %%fs:0x1034-0x54\n"
192 "movl %%fs:0x1034-0x54, %0\n"
193 "1:\n"
194 : "=r"(level)
195 :
196 : "memory");
197 #else
198 #error Unsupported target platform
199 #endif
200 return !level;
201 }
202
203 void Debug::_message(const char* msg) {
128 if (enabled_) { 204 if (enabled_) {
129 Sandbox::SysCalls sys; 205 Sandbox::SysCalls sys;
130 size_t len = strlen(msg); 206 size_t len = strlen(msg);
131 if (len && msg[len-1] != '\n') { 207 if (len && msg[len-1] != '\n') {
132 // Write operations should be atomic, so that we don't interleave 208 // Write operations should be atomic, so that we don't interleave
133 // messages from multiple threads. Append a newline, if it is not 209 // messages from multiple threads. Append a newline, if it is not
134 // already there. 210 // already there.
135 char copy[len + 1]; 211 char copy[len + 1];
136 memcpy(copy, msg, len); 212 memcpy(copy, msg, len);
137 copy[len] = '\n'; 213 copy[len] = '\n';
138 Sandbox::write(sys, 2, copy, len + 1); 214 Sandbox::write(sys, 2, copy, len + 1);
139 } else { 215 } else {
140 Sandbox::write(sys, 2, msg, len); 216 Sandbox::write(sys, 2, msg, len);
141 } 217 }
142 } 218 }
143 } 219 }
144 220
145 void Debug::syscall(int sysnum, const char* msg, int call) { 221 void Debug::message(const char* msg) {
222 if (enabled_) {
223 if (enter()) {
224 _message(msg);
225 }
226 leave();
227 }
228 }
229
230 void Debug::gettimeofday(long long* tm) {
231 if (tm) {
232 struct timeval tv;
233 #if defined(__i386__)
234 // Zero out the lastSyscallNum, so that we don't try to coalesce
235 // calls to gettimeofday(). For debugging purposes, we need the
236 // exact time.
237 asm volatile("movl $0, %fs:0x102C-0x54");
238 #elif !defined(__x86_64__)
239 #error Unsupported target platform
240 #endif
241 ::gettimeofday(&tv, NULL);
242 *tm = 1000ULL*1000ULL*static_cast<unsigned>(tv.tv_sec) +
243 static_cast<unsigned>(tv.tv_usec);
244 }
245 }
246
247 void Debug::syscall(long long* tm, int sysnum, const char* msg, int call) {
146 // This function gets called from the system call wrapper. Avoid calling 248 // This function gets called from the system call wrapper. Avoid calling
147 // any library functions that themselves need system calls. 249 // any library functions that themselves need system calls.
148 if (enabled_) { 250 if (enabled_) {
149 const char *sysname = NULL; 251 if (enter() || !tm) {
150 if (sysnum >= 0 && sysnum < numSyscallNames_) { 252 gettimeofday(tm);
151 sysname = syscallNames_[sysnum]; 253
254 const char *sysname = NULL;
255 if (sysnum >= 0 && sysnum < numSyscallNames_) {
256 sysname = syscallNames_[sysnum];
257 }
258 static const char kUnnamedMessage[] = "Unnamed syscall #";
259 char unnamed[40];
260 if (!sysname) {
261 memcpy(unnamed, kUnnamedMessage, sizeof(kUnnamedMessage) - 1);
262 itoa(unnamed + sizeof(kUnnamedMessage) - 1, sysnum);
263 sysname = unnamed;
264 }
265 #if defined(__NR_socketcall) || defined(__NR_ipc)
266 char extra[40];
267 *extra = '\000';
268 #if defined(__NR_socketcall)
269 if (sysnum == __NR_socketcall) {
270 static const char* socketcall_name[] = {
271 0, "socket", "bind", "connect", "listen", "accept", "getsockname",
272 "getpeername", "socketpair", "send", "recv", "sendto","recvfrom",
273 "shutdown", "setsockopt", "getsockopt", "sendmsg", "recvmsg",
274 "accept4"
275 };
276 if (call >= 1 &&
277 call < (int)(sizeof(socketcall_name)/sizeof(char *))) {
278 strcat(strcpy(extra, " "), socketcall_name[call]);
279 } else {
280 itoa(strcpy(extra, " #") + 2, call);
281 }
282 }
283 #endif
284 #if defined(__NR_ipc)
285 if (sysnum == __NR_ipc) {
286 static const char* ipc_name[] = {
287 0, "semop", "semget", "semctl", "semtimedop", 0, 0, 0, 0, 0, 0,
288 "msgsnd", "msgrcv", "msgget", "msgctl", 0, 0, 0, 0, 0, 0,
289 "shmat", "shmdt", "shmget", "shmctl" };
290 if (call >= 1 && call < (int)(sizeof(ipc_name)/sizeof(char *)) &&
291 ipc_name[call]) {
292 strcat(strcpy(extra, " "), ipc_name[call]);
293 } else {
294 itoa(strcpy(extra, " #") + 2, call);
295 }
296 }
297 #endif
298 #else
299 static const char extra[1] = { 0 };
300 #endif
301 char buf[strlen(sysname) + strlen(extra) + (msg ? strlen(msg) : 0) + 4];
302 strcat(strcat(strcat(strcat(strcpy(buf, sysname), extra), ": "),
303 msg ? msg : ""), "\n");
304 _message(buf);
152 } 305 }
153 char unnamed[40] = "Unnamed syscall #"; 306 leave();
154 if (!sysname) {
155 itoa(const_cast<char *>(strrchr(sysname = unnamed, '\000')), sysnum);
156 }
157 #if defined(__NR_socketcall) || defined(__NR_ipc)
158 char extra[40];
159 *extra = '\000';
160 #if defined(__NR_socketcall)
161 if (sysnum == __NR_socketcall) {
162 static const char* socketcall_name[] = {
163 0, "socket", "bind", "connect", "listen", "accept", "getsockname",
164 "getpeername", "socketpair", "send", "recv", "sendto","recvfrom",
165 "shutdown", "setsockopt", "getsockopt", "sendmsg", "recvmsg",
166 "accept4"
167 };
168 if (call >= 1 && call < (int)(sizeof(socketcall_name)/sizeof(char *))) {
169 strcat(strcpy(extra, " "), socketcall_name[call]);
170 } else {
171 itoa(strcpy(extra, " #") + 2, call);
172 }
173 }
174 #endif
175 #if defined(__NR_ipc)
176 if (sysnum == __NR_ipc) {
177 static const char* ipc_name[] = {
178 0, "semop", "semget", "semctl", "semtimedop", 0, 0, 0, 0, 0, 0,
179 "msgsnd", "msgrcv", "msgget", "msgctl", 0, 0, 0, 0, 0, 0,
180 "shmat", "shmdt", "shmget", "shmctl" };
181 if (call >= 1 && call < (int)(sizeof(ipc_name)/sizeof(char *)) &&
182 ipc_name[call]) {
183 strcat(strcpy(extra, " "), ipc_name[call]);
184 } else {
185 itoa(strcpy(extra, " #") + 2, call);
186 }
187 }
188 #endif
189 #else
190 static const char *extra = "";
191 #endif
192 char buf[strlen(sysname) + strlen(extra) + (msg ? strlen(msg) : 0) + 4];
193 strcat(strcat(strcat(strcat(strcpy(buf, sysname), extra), ": "),
194 msg ? msg : ""), "\n");
195 message(buf);
196 } 307 }
197 } 308 }
198 309
199 char* Debug::itoa(char* s, int n) { 310 char* Debug::itoa(char* s, int n) {
200 // Remember return value 311 // Remember return value
201 char *ret = s; 312 char *ret = s;
202 313
203 // Insert sign for negative numbers 314 // Insert sign for negative numbers
204 if (n < 0) { 315 if (n < 0) {
205 *s++ = '-'; 316 *s++ = '-';
(...skipping 11 matching lines...) Expand all
217 // Reverse order of digits 328 // Reverse order of digits
218 while (start < s) { 329 while (start < s) {
219 char ch = *s; 330 char ch = *s;
220 *s-- = *start; 331 *s-- = *start;
221 *start++ = ch; 332 *start++ = ch;
222 } 333 }
223 334
224 return ret; 335 return ret;
225 } 336 }
226 337
338 void Debug::elapsed(long long tm, int sysnum, int call) {
339 if (enabled_) {
340 if (enter()) {
341 // Compute the time that has passed since the system call started.
342 long long delta;
343 gettimeofday(&delta);
344 delta -= tm;
345
346 // Format "Elapsed time: %d.%03dms" without using sprintf().
347 char buf[80];
348 itoa(strrchr(strcpy(buf, "Elapsed time: "), '\000'), delta/1000);
349 delta %= 1000;
350 strcat(buf, delta < 100 ? delta < 10 ? ".00" : ".0" : ".");
351 itoa(strrchr(buf, '\000'), delta);
352 strcat(buf, "ms");
353
354 // Print system call name and elapsed time.
355 syscall(NULL, sysnum, buf, call);
356 }
357 leave();
358 }
359 }
360
227 } // namespace 361 } // namespace
228 362
229 #endif // NDEBUG 363 #endif // NDEBUG
OLDNEW
« no previous file with comments | « sandbox/linux/seccomp/debug.h ('k') | sandbox/linux/seccomp/exit.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698