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

Side by Side Diff: experimental/linux_oop_debugger/debug_api_linux.cc

Issue 10928195: First round of dead file removal (Closed) Base URL: https://github.com/samclegg/nativeclient-sdk.git@master
Patch Set: Created 8 years, 3 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
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Native Client 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 #include "debug_api_linux.h"
5
6 #include <errno.h>
7 #include <memory.h>
8 #include <signal.h>
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <sys/syscall.h>
12 #include <sys/types.h>
13 #include <sys/user.h>
14 #include <sys/wait.h>
15 #include <unistd.h>
16
17 #include <deque>
18 #include <string>
19
20 typedef int64_t ptrace_result_t;
21
22 void Split(const char* str_in,
23 const char* delimiters,
24 std::deque<std::string>* out) {
25 char c = 0;
26 std::string str;
27 while (c = *str_in++) {
28 if (strchr(delimiters, c)) {
29 if (str.size()) {
30 out->push_back(str);
31 str.clear();
32 }
33 } else if ((c != '\r') && (c != '\n')) {
34 str.push_back(c);
35 }
36 }
37 if (str.size())
38 out->push_back(str);
39 }
40
41 std::string GetAppPathOutOfCmdLine(const char* cmd_line) {
42 std::deque<std::string> words;
43 Split(cmd_line, " \t", &words);
44 if (words.size() > 0)
45 return words[0];
46 return cmd_line;
47 }
48
49 std::string GetAppNameOutOfCmdLine(const char* cmd_line) {
50 std::string path = GetAppPathOutOfCmdLine(cmd_line);
51 std::deque<std::string> words;
52 Split(path.c_str(), "/", &words);
53 if (words.size() > 0)
54 return words[words.size() - 1];
55 return cmd_line;
56 }
57
58 namespace {
59 const int kOutputDebugStringSignal = SIGUSR1;
60 const int kOutputDebugStringSize = 4 * 1024;
61 } // namespace
62
63 namespace debug {
64 bool DebugApi::PostASignal(pid_t pid, int signo, int sig_value) {
65 sigval val;
66 val.sival_int = sig_value;
67 return (0 == sigqueue(pid, signo, val));
68 }
69
70 bool DebugApi::PostASignal(pid_t pid, int signo, void* sig_value) {
71 sigval val;
72 val.sival_ptr = sig_value;
73 return (0 == sigqueue(pid, signo, val));
74 }
75
76 bool DebugApi::ReadDebugString(DebugEvent* de, std::string* string) {
77 if (DebugEvent::OUTPUT_DEBUG_STRING != de->event_code_)
78 return false;
79
80 char buff[kOutputDebugStringSize + 1];
81 memset(buff, 'c', sizeof(buff));
82 void* addr = reinterpret_cast<void*>(de->signal_value_.sival_ptr);
83 size_t readed_bytes = 0;
84 bool res = ReadProcessMemory(de->process_id_,
85 addr,
86 buff,
87 sizeof(buff) - 1,
88 &readed_bytes);
89 // printf("ReadProcessMemory->%s readed_bytes = %d\n",
90 // res ? "ok" : "err", (int)readed_bytes);
91 if (0 == readed_bytes)
92 return false;
93
94 buff[readed_bytes] = 0;
95 if (NULL != string)
96 *string = buff;
97 return true;
98 }
99
100 bool DebugApi::ContinueDebugEvent(pid_t process_id, int signo) {
101 ptrace_result_t res = ptrace(PTRACE_CONT, process_id, 0, signo);
102 // printf("ptrace(PTRACE_CONT(pid=%d signo=%d) -> %ld\n",
103 // process_id, signo, res);
104 return (0 == res);
105 }
106
107 bool DebugApi::GetNewChildPid(pid_t pid, pid_t* child_pid_out) {
108 // PTRACE_GETEVENTMSG
109 // TODO(garianov): implement
110 ptrace_result_t res = ptrace(PTRACE_GETEVENTMSG, pid, 0, 0);
111 return (0 == res);
112 }
113
114 bool DebugApi::StartProcess(const char* cmd_line,
115 bool trace,
116 pid_t* child_pid_out) {
117 std::string path = GetAppPathOutOfCmdLine(cmd_line);
118 std::string app_name = GetAppNameOutOfCmdLine(cmd_line);
119
120 pid_t child_pid = fork();
121 printf("fork -> %d\n", child_pid);
122 if (-1 == child_pid)
123 return false;
124
125 if (0 == child_pid) {
126 // in child
127 if (trace)
128 ptrace(PTRACE_TRACEME, 0, NULL, NULL);
129
130 printf("In child: pid=%d ppid=%d\n", getpid(), getppid());
131 fflush(stdout);
132
133 int res = execl(path.c_str(), app_name.c_str(), "", NULL);
134
135 // TODO(garianov): how to communicate failure of execl to the debugger
136 // process?
137 // My guess is parent proc/debugger will get SIGTERM signal or TERM debug ev ent...
138 exit(13);
139 } else {
140 // in parent
141 if (NULL != child_pid_out)
142 *child_pid_out = child_pid;
143 }
144 return true;
145 }
146
147 bool DebugApi::SetupProc(pid_t pid) {
148 intptr_t mask =
149 PTRACE_O_TRACEFORK |
150 PTRACE_O_TRACEVFORK |
151 PTRACE_O_TRACECLONE ;
152 // PTRACE_O_TRACEEXEC |
153 // PTRACE_O_TRACEEXIT;
154 void* data = reinterpret_cast<void*>(mask);
155 ptrace_result_t res = ptrace(PTRACE_SETOPTIONS, pid, 0, data);
156 printf("Setup PTRACE_O_TRACEFORK option (0x%p) on pid=%d -> %ld\n",
157 data,
158 pid,
159 res);
160 fflush(stdout);
161 if (0 != res) {
162 printf("Error: ptrace(PTRACE_SETOPTIONS(pid=%d) -> %ld\n", pid, res);
163 printf("Errno: %s\n", strerror(errno));
164 }
165 return (0 != res);
166 }
167
168 bool DebugApi::DebugBreak(pid_t pid) {
169 bool res = (0 == kill(pid, SIGSTOP));
170 if (!res) {
171 printf("kill failed\n");
172 printf("Errno: %s\n", strerror(errno));
173 fflush(stdout);
174 }
175 return res;
176 }
177
178 bool DebugApi::SingleStep(pid_t pid) {
179 printf("SingleStep(%d)\n", pid);
180 ptrace_result_t res = ptrace(PTRACE_SINGLESTEP, pid, 0, 0);
181 return (0 == res);
182 }
183
184
185 bool DebugApi::WriteProcessMemory(pid_t pid,
186 void* addr,
187 void* src,
188 size_t size,
189 size_t* written_bytes_out) {
190 size_t written_bytes = 0;
191 size_t left_bytes = size;
192 ptrace_result_t res = 0;
193 const size_t bundle_sz = sizeof(res);
194 unsigned char* ptr_src = reinterpret_cast<unsigned char*>(src);
195 unsigned char* ptr_addr = reinterpret_cast<unsigned char*>(addr);
196
197 // Read first few bytes that rea not aligned on 4 (or 8 on 64-bit)
198 // bytes, if any.
199 size_t offset = reinterpret_cast<size_t>(addr);
200 size_t offset_from_4bytes = offset % bundle_sz;
201 if (0 != offset_from_4bytes) {
202 // printf("offset_from_4bytes = %d\n", (int)offset_from_4bytes);
203 unsigned char* beg_addr =
204 reinterpret_cast<unsigned char*>(offset - offset_from_4bytes);
205 res = ptrace(PTRACE_PEEKDATA, pid, beg_addr, 0);
206 // printf("ptrace(PTRACE_PEEKDATA(%p) -> 0x%lX\n", beg_addr, res);
207 if (0 != errno) {
208 // printf("%d ptrace -> %d\n", __LINE__, errno);
209 return false;
210 }
211 unsigned char* p =
212 reinterpret_cast<unsigned char*>(&res) + offset_from_4bytes;
213 written_bytes = bundle_sz - offset_from_4bytes;
214 if (written_bytes > size)
215 written_bytes = size;
216
217 memcpy(p, ptr_src, written_bytes);
218 ptrace_result_t res2 = ptrace(PTRACE_POKEDATA, pid, beg_addr, res);
219 // printf("ptrace(PTRACE_POKEDATA(%p, 0x%lX) -> 0x%lX\n",
220 // beg_addr,
221 // res,
222 // res2);
223 if (0 != res2) {
224 // printf("%d ptrace(PTRACE_POKEDATA) -> %d\n", errno, __LINE__);
225 return false;
226 }
227
228 ptr_src += written_bytes;
229 ptr_addr += written_bytes;
230 left_bytes -= written_bytes;
231 }
232
233 while (left_bytes) {
234 size_t wr_bytes = bundle_sz;
235 if (wr_bytes > left_bytes)
236 wr_bytes = left_bytes;
237
238 ptrace_result_t data = 0;
239 if (left_bytes < bundle_sz) {
240 data = ptrace(PTRACE_PEEKDATA, pid, ptr_addr, 0);
241 if (0 != errno) {
242 // printf("%d ptrace(PTRACE_PEEKDATA) -> 0x%lX\n", __LINE__, data);
243 return false;
244 }
245 // printf("ptrace(PTRACE_PEEKDATA(%p) -> 0x%lX\n", ptr_addr, data);
246 }
247 memcpy(&data, ptr_src, wr_bytes);
248 // printf("memcpy... %X\n", (unsigned int)(*ptr_src));
249 // printf("PTRACE_POKEDATA(%p) %lX\n", ptr_addr, data);
250
251 ptrace_result_t res = ptrace(PTRACE_POKEDATA, pid, ptr_addr, data);
252 if (0 != res) {
253 printf("%d ptrace(PTRACE_POKEDATA) -> 0x%lX\n", __LINE__, res);
254 return false;
255 }
256
257 written_bytes += wr_bytes;
258 ptr_src += written_bytes;
259 ptr_addr += written_bytes;
260 left_bytes -= wr_bytes;
261 }
262
263 if (NULL != written_bytes_out)
264 *written_bytes_out = written_bytes;
265 return (size == written_bytes);
266 }
267
268 bool DebugApi::ReadProcessMemory(pid_t pid,
269 void* addr,
270 void* dest,
271 size_t size,
272 size_t* readed_bytes_out) {
273 size_t readed_bytes = 0;
274 size_t left_bytes = size;
275 ptrace_result_t res = 0;
276 const size_t bundle_sz = sizeof(res);
277 char* ptr_dest = reinterpret_cast<char*>(dest);
278 char* ptr_addr = reinterpret_cast<char*>(addr);
279 //printf("DebugApi::ReadProcessMemory(%d, %p, %d)\n", pid, addr, (int)size);
280 //printf("left_bytes = %d\n", (int)left_bytes);
281
282 // Read first few bytes that rea not aligned on 4 (or 8 on 64-bit)
283 // bytes, if any.
284 size_t offset = reinterpret_cast<size_t>(addr);
285 size_t offset_from_4bytes = offset % bundle_sz;
286 //printf("===>>>>> offset_from_4bytes=%ld\n", offset_from_4bytes);
287 fflush(stdout);
288 if (0 != offset_from_4bytes) {
289 char* beg_addr = reinterpret_cast<char*>(offset - offset_from_4bytes);
290 res = ptrace(PTRACE_PEEKDATA, pid, beg_addr, 0);
291 //printf("ptrace(PTRACE_PEEKDATA(%p) -> 0x%lX\n", beg_addr, res);
292 if (0 != errno) {
293 //printf("ptrace -> %d\n", errno);
294 //printf("Errno: %s\n", strerror(errno));
295 return false;
296 }
297 char* src = reinterpret_cast<char*>(&res) + offset_from_4bytes;
298 readed_bytes = bundle_sz - offset_from_4bytes;
299 //printf("readed_bytes = %d\n", (int)readed_bytes);
300 memcpy(ptr_dest, src, readed_bytes);
301 ptr_dest += readed_bytes;
302 ptr_addr += readed_bytes;
303 if (readed_bytes > left_bytes)
304 left_bytes = 0;
305 else
306 left_bytes -= readed_bytes;
307 //printf("left_bytes = %d\n", (int)left_bytes);
308 }
309
310 while (left_bytes) {
311 //printf("left_bytes = %d\n", (int)left_bytes);
312 res = ptrace(PTRACE_PEEKDATA, pid, ptr_addr, 0);
313 //printf("ptrace(PTRACE_PEEKDATA(%p) -> 0x%lX\n", ptr_addr, res);
314 if (0 != errno) {
315 //printf("Errno: %s\n", strerror(errno));
316 break;
317 }
318 size_t rd_bytes = bundle_sz;
319 if (rd_bytes > left_bytes)
320 rd_bytes = left_bytes;
321
322 //printf("rd_bytes = %d\n", (int)rd_bytes);
323 memcpy(ptr_dest, &res, rd_bytes);
324 readed_bytes += rd_bytes;
325 ptr_dest += rd_bytes;
326 ptr_addr += rd_bytes;
327 left_bytes -= rd_bytes;
328 }
329 if (NULL != readed_bytes_out)
330 *readed_bytes_out = readed_bytes;
331 //printf("size=%d readed_bytes=%d\n", (int)size, (int)readed_bytes);
332 return (size <= readed_bytes);
333 }
334
335 bool DebugApi::GetRax(pid_t pid, char** rax) {
336 user_regs_struct context;
337 if (!ReadThreadContext(pid, &context))
338 return false;
339
340 if (NULL != rax)
341 *rax = reinterpret_cast<char*>(context.rax);
342 return true;
343 }
344
345 bool DebugApi::GetIp(pid_t pid, char** ip) {
346 user_regs_struct context;
347 if (!ReadThreadContext(pid, &context))
348 return false;
349
350 if (NULL != ip) {
351 *ip = reinterpret_cast<char*>(context.rip);
352 printf("ReadThreadContext-> ip = %p, ip = 0x%lx\n", *ip, context.rip);
353 }
354 return true;
355 }
356
357 bool DebugApi::SetIp(pid_t pid, char* ip) {
358 user_regs_struct context;
359 if (!ReadThreadContext(pid, &context))
360 return false;
361 if (NULL != ip)
362 context.rip = reinterpret_cast<u_int64_t>(ip);
363 return WriteThreadContext(pid, &context);
364 }
365
366 bool DebugApi::ReadThreadContext(pid_t pid, user_regs_struct* context) {
367 int ret = ptrace(PTRACE_GETREGS, pid, NULL, context);
368 // printf("ptrace(PTRACE_GETREGS, -> %d\n", ret);
369 return (0 == ret);
370 }
371
372 bool DebugApi::WriteThreadContext(pid_t pid, user_regs_struct* context) {
373 printf("calling ptrace (PTRACE_SETREGS, pid=%d\n", pid);
374 fflush(stdout);
375
376 int ret = ptrace(PTRACE_SETREGS, pid, NULL, context);
377 printf("ptrace (PTRACE_SETREGS, -> %d\n", ret);
378 fflush(stdout);
379 return (0 == ret);
380 }
381
382 #define BBB(x) printf("\t\"" #x "\" = \"%lX\",\n", context.x)
383
384 void DebugApi::PrintThreadContext(const user_regs_struct& context) {
385 printf("context = {\n");
386 BBB(r15);
387 BBB(r14);
388 BBB(r13);
389 BBB(r12);
390 BBB(rbp);
391 BBB(rbx);
392 BBB(r11);
393 BBB(r10);
394 BBB(r9);
395 BBB(r8);
396 BBB(rax);
397 BBB(rcx);
398 BBB(rdx);
399 BBB(rsi);
400 BBB(rdi);
401 BBB(orig_rax);
402 BBB(rip);
403 BBB(cs);
404 BBB(eflags);
405 BBB(rsp);
406 BBB(ss);
407 BBB(fs_base);
408 BBB(gs_base);
409 BBB(ds);
410 BBB(es);
411 BBB(fs);
412 BBB(gs);
413 printf("}\n");
414 }
415
416 bool DebugApi::WaitForDebugEvent(DebugEvent* de) {
417 int status = 0;
418 int options = WNOHANG; // | WUNTRACED | WCONTINUED;
419 options |= __WALL;
420 int res = waitpid(-1, &status, options);
421 if (-1 == res)
422 return false;
423
424 bool recv_event = (0 != res);
425 if (recv_event) {
426 de->Reset();
427 de->process_id_ = res;
428
429 user_regs_struct context;
430 if (ReadThreadContext(de->process_id_, &context)) {
431 de->ip_ = reinterpret_cast<char*>(context.rip);
432 }
433 siginfo_t si;
434 memset(&si, 0, sizeof(si));
435 ptrace_result_t res = ptrace(PTRACE_GETSIGINFO, de->process_id_, 0, &si);
436 // printf("ptrace(PTRACE_GETSIGINFO -> %ld\n", res);
437 if (0 == res) {
438 de->signal_code_ = si.si_code;
439 de->signal_value_ = si.si_value;
440 if ((SIGTRAP == de->signal_no_) ||
441 (SIGSEGV == de->signal_no_) ||
442 (SIGILL == de->signal_no_) ||
443 (SIGFPE == de->signal_no_) ||
444 (SIGBUS == de->signal_no_))
445 de->addr_ = reinterpret_cast<char*>(si.si_addr);
446
447 if ((SIGTRAP == de->signal_no_) && (EVENT_CLONE == si.si_code)) {
448 // TODO(garianov): get children pid
449 // PTRACE_GETEVENTMSG
450 }
451 }
452
453
454 if (WIFEXITED(status)) {
455 de->event_code_ = DebugEvent::PROCESS_EXITED;
456 de->exit_code_ = WEXITSTATUS(status);
457 } else if (WIFSIGNALED(status)) {
458 de->event_code_ = DebugEvent::PROCESS_TERMINATED;
459 de->signal_no_ = WTERMSIG(status);
460 } else if (WIFSTOPPED(status)) {
461 de->event_code_ = DebugEvent::PROCESS_STOPPED;
462 de->signal_no_ = WSTOPSIG(status);
463
464 if (SIGTRAP == de->signal_no_) {
465 de->event_code_ = DebugEvent::HIT_BREAKPOINT;
466 if (TRAP_TRACE == de->signal_code_)
467 de->event_code_ = DebugEvent::SINGLE_STEP_TRAP;
468 } else if (kOutputDebugStringSignal == de->signal_no_) {
469 de->event_code_ = DebugEvent::OUTPUT_DEBUG_STRING;
470 }
471 } else if (WIFCONTINUED(status)) {
472 de->event_code_ = DebugEvent::PROCESS_CONTINUED_WITH_SIGCONT;
473 }
474 }
475 return recv_event;
476 }
477
478 bool DebugApi::EnableSingleStep(pid_t pid, bool enable) {
479 user_regs_struct context;
480 if (ReadThreadContext(pid, &context)) {
481 if (enable)
482 context.eflags |= 1 << 8;
483 else
484 context.eflags &= ~(1 << 8);
485 return WriteThreadContext(pid, &context);
486 }
487 return false;
488 }
489
490 void DebugEvent::Reset() {
491 memset(this, 0, sizeof(*this));
492 }
493
494 #define BB(x, desc) case x: return #x ": " desc
495
496 const char* GetSigCodeName(int signo, int sig_code) {
497 if (SIGILL == signo) {
498 switch (sig_code) {
499 BB(ILL_ILLOPC, "Illegal opcode");
500 BB(ILL_ILLADR, "Illegal addressing mode");
501 BB(ILL_ILLTRP, "Illegal trap");
502 BB(ILL_PRVOPC, "Privileged opcode");
503 BB(ILL_PRVREG, "Privileged register");
504 BB(ILL_COPROC, "Coprocessor error");
505 BB(ILL_BADSTK, "Internal stack error");
506 }
507 } else if (SIGFPE == signo) {
508 switch (sig_code) {
509 BB(FPE_INTDIV, "Integer divide by zero");
510 BB(FPE_INTOVF, "Integer overflow");
511 BB(FPE_FLTDIV, "Floating point divide by zero");
512 BB(FPE_FLTOVF, "Floating point overflow");
513 BB(FPE_FLTUND, "Floating point underflow");
514 BB(FPE_FLTRES, "Floating point inexact result");
515 BB(FPE_FLTINV, "Floating point invalid operation");
516 BB(FPE_FLTSUB, "Subscript out of range");
517 }
518 } else if (SIGSEGV == signo) {
519 switch (sig_code) {
520 BB(SEGV_MAPERR, "Address not mapped to object");
521 BB(SEGV_ACCERR, "Invalid permissions for mapped object");
522 }
523 } else if (SIGBUS == signo) {
524 switch (sig_code) {
525 BB(BUS_ADRALN, "Invalid address alignment");
526 BB(BUS_ADRERR, "Non-existant physical address");
527 BB(BUS_OBJERR, "Object specific hardware error");
528 }
529 } else if (SIGTRAP == signo) {
530 switch (sig_code) {
531 BB(TRAP_BRKPT, "Process breakpoint");
532 BB(TRAP_TRACE, "Process trace trap, aka single step");
533 BB(EVENT_FORK, "");
534 BB(EVENT_VFORK, "");
535 BB(EVENT_CLONE, "");
536 BB(EVENT_EXEC, "");
537 BB(EVENT_VFORK_DONE, "");
538 BB(EVENT_EXIT, "");
539 }
540 } else if (SIGCHLD == signo) {
541 switch (sig_code) {
542 BB(CLD_EXITED, "Child has exited");
543 BB(CLD_KILLED, "Child was killed");
544 BB(CLD_DUMPED, "Child terminated abnormally");
545 BB(CLD_TRAPPED, "Traced child has trapped");
546 BB(CLD_STOPPED, "Child has stopped");
547 BB(CLD_CONTINUED, "Stopped child has continued");
548 }
549 } else if (SIGPOLL == signo) {
550 switch (sig_code) {
551 BB(POLL_IN, "Data input available");
552 BB(POLL_OUT, "Output buffers available");
553 BB(POLL_MSG, "Input message available");
554 BB(POLL_ERR, "I/O error");
555 BB(POLL_PRI, "High priority input available");
556 BB(POLL_HUP, "Device disconnected");
557 }
558 }
559 switch (sig_code) {
560 BB(SI_ASYNCNL, "Sent by asynch name lookup completion");
561 BB(SI_TKILL, "Sent by tkill");
562 BB(SI_SIGIO, "Sent by queued SIGIO");
563 BB(SI_ASYNCIO, "Sent by AIO completion");
564 BB(SI_MESGQ, "Sent by real time mesq state change");
565 BB(SI_TIMER, "Sent by timer expiration");
566 BB(SI_QUEUE, "Sent by sigqueue");
567 BB(SI_USER, "Sent by kill, sigsend, raise");
568 BB(SI_KERNEL, "Send by kernel");
569 }
570 return "";
571 }
572
573 const char* GetSignalName(int signo) {
574 switch (signo) {
575 BB(SIGHUP, "Hangup (POSIX)");
576 BB(SIGINT, "Interrupt (ANSI)");
577 BB(SIGQUIT, "Quit (POSIX)");
578 BB(SIGILL, "Illegal instruction (ANSI)");
579 BB(SIGTRAP, "Trace trap (POSIX)");
580 BB(SIGABRT, "==SIGIOT. Abort (ANSI) == IOT trap (4.2 BSD)");
581 BB(SIGBUS, "BUS error (4.2 BSD)");
582 BB(SIGFPE, "Floating-point exception (ANSI)");
583 BB(SIGKILL, "Kill, unblockable (POSIX)");
584 BB(SIGUSR1, "User-defined signal 1 (POSIX)");
585 BB(SIGSEGV, "Segmentation violation (ANSI)");
586 BB(SIGUSR2, "User-defined signal 2 (POSIX)");
587 BB(SIGPIPE, "Broken pipe (POSIX)");
588 BB(SIGALRM, "Alarm clock (POSIX)");
589 BB(SIGTERM, "Termination (ANSI)");
590 BB(SIGSTKFLT, "Stack fault");
591 BB(SIGCHLD, "Child status has changed (POSIX)");
592 BB(SIGCONT, "Continue (POSIX)");
593 BB(SIGSTOP, "Stop, unblockable (POSIX)");
594 BB(SIGTSTP, "Keyboard stop (POSIX)");
595 BB(SIGTTIN, "Background read from tty (POSIX)");
596 BB(SIGTTOU, "Background write to tty (POSIX)");
597 BB(SIGURG, "Urgent condition on socket (4.2 BSD)");
598 BB(SIGXCPU, "CPU limit exceeded (4.2 BSD)");
599 BB(SIGXFSZ, "File size limit exceeded (4.2 BSD)");
600 BB(SIGVTALRM, "Virtual alarm clock (4.2 BSD)");
601 BB(SIGPROF, "Profiling alarm clock (4.2 BSD)");
602 BB(SIGWINCH, "Window size change (4.3 BSD, Sun)");
603 BB(SIGIO,
604 "I/O now possible (4.2 BSD) /"
605 "Pollable event occurred (System V)");
606 BB(SIGPWR, "Power failure restart (System V)");
607 BB(SIGSYS, "Bad system call");
608 }
609 return "";
610 }
611
612 #define AAA(x) case x: ev_name = #x; break
613
614 void DebugEvent::Print() {
615 const char* ev_name = "UNKNOWN";
616 switch (event_code_) {
617 AAA(HIT_BREAKPOINT);
618 AAA(OUTPUT_DEBUG_STRING);
619 AAA(SINGLE_STEP_TRAP);
620 AAA(PROCESS_TERMINATED);
621 AAA(PROCESS_EXITED);
622 AAA(PROCESS_STOPPED);
623 AAA(PROCESS_CONTINUED_WITH_SIGCONT);
624 }
625
626 printf("\"DebugEvent\" : {\n");
627 printf("\t\"process_id_\" : \"%d\",\n", process_id_);
628 printf("\t\"event_code_\" : \"%s\",\n", ev_name);
629
630 printf("\t\"signal_no_\" : \"%d\",", signal_no_);
631 if (0 != signal_no_)
632 printf(" //%s", GetSignalName(signal_no_));
633 printf("\n");
634
635 printf("\t\"signal_code_\" : \"%d\",", signal_code_);
636 const char* sig_code_name = GetSigCodeName(signal_no_, signal_code_);
637 if (strlen(sig_code_name) > 0 )
638 printf(" //%s", sig_code_name);
639 printf("\n");
640
641 printf("\t\"exit_code_\" : \"%d\",\n", exit_code_);
642 printf("\t\"ip_\" : \"%p\",\n", ip_);
643 printf("\t\"addr_\" : \"%p\",\n", addr_);
644 printf("}\n");
645 }
646 } // namespace debug
647
OLDNEW
« no previous file with comments | « experimental/linux_oop_debugger/debug_api_linux.h ('k') | experimental/linux_oop_debugger/debug_blob.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698