| Index: experimental/mac_debugger/debug_api_mac.cc
|
| diff --git a/experimental/mac_debugger/debug_api_mac.cc b/experimental/mac_debugger/debug_api_mac.cc
|
| deleted file mode 100644
|
| index 6f3e14678b3295330785267d822de36962e2b866..0000000000000000000000000000000000000000
|
| --- a/experimental/mac_debugger/debug_api_mac.cc
|
| +++ /dev/null
|
| @@ -1,591 +0,0 @@
|
| -// Copyright (c) 2011 The Native Client Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -#include "debug_api_mac.h"
|
| -
|
| -#include <errno.h>
|
| -#include <memory.h>
|
| -#include <stdio.h>
|
| -#include <stdlib.h>
|
| -
|
| -#ifndef _WIN32
|
| -#include <signal.h>
|
| -#include <sys/syscall.h>
|
| -#include <sys/types.h>
|
| -#include <sys/user.h>
|
| -#include <sys/wait.h>
|
| -#include <unistd.h>
|
| -//#include <osfmk/vm/vm_map.h>
|
| -#else
|
| -#include "mac_sys_mock.h"
|
| -#endif
|
| -
|
| -#include <deque>
|
| -#include <string>
|
| -
|
| -typedef int64_t ptrace_result_t;
|
| -extern "C" boolean_t exc_server(mach_msg_header_t* inhdr, mach_msg_header_t* outhdr);
|
| -
|
| -#define CALL_KERN(x) do { int res = x; if (0 != res) {printf("%s error: %d\n", #x, res); return false;}\
|
| -else printf("%s ok!\n", #x);} while (false)
|
| -#define CALL_KERN2(x) do { int res = x; if (0 != res) {printf("%s error: %d\n", #x, res); pthread_exit((void*)x);}\
|
| -else printf("%s ok!\n", #x);} while (false)
|
| -
|
| -#define PAGE_MASK (page_size_ - 1)
|
| -#define vm_map_trunc_page(x) ((mach_vm_address_t)(x) & ~((signed int)PAGE_MASK))
|
| -#define vm_map_round_page(x) (((mach_vm_address_t)(x) + PAGE_MASK) & (~(signed int)PAGE_MASK))
|
| -
|
| -extern "C" kern_return_t catch_exception_raise(mach_port_t exception_port,
|
| - mach_port_t thread,
|
| - mach_port_t task,
|
| - exception_type_t exceptio,
|
| - mach_exception_data_t code,
|
| - mach_msg_type_number_t code_cnt)
|
| -#ifndef _WIN32
|
| - __attribute__((visibility("default")))
|
| -#endif
|
| - ;
|
| -
|
| -debug::DebugEvent* glb_debug_event = NULL;
|
| -
|
| -extern "C" kern_return_t catch_exception_raise(mach_port_t exception_port,
|
| - mach_port_t thread,
|
| - mach_port_t task,
|
| - exception_type_t exceptio,
|
| - mach_exception_data_t code,
|
| - mach_msg_type_number_t code_cnt) {
|
| - int pid = 0;
|
| - pid_for_task(task, &pid);
|
| - printf("Got exception %d(0x%x):0x%p from task:thread 0x%d:0x%x pid=0x%x\n>>", (int)exceptio, (int)exceptio, code, task, thread, pid);
|
| - if (0 == thread)
|
| - return KERN_SUCCESS;
|
| - if (NULL != glb_debug_event) {
|
| - glb_debug_event->pid_ = pid;
|
| - glb_debug_event->process_state_ = debug::PROCESS_STOPPED;
|
| - glb_debug_event->signal_no_ = MACH_EXCEPTIONS_START_CODE + exceptio;
|
| - glb_debug_event->exit_code_ = 0;
|
| - glb_debug_event->task_ = task;
|
| - glb_debug_event->thread_ = thread;
|
| - printf("Suspending task 0x%x\n", task);
|
| - if (exceptio != 10) {
|
| - CALL_KERN(::task_suspend(task));
|
| - }
|
| - }
|
| - return (exceptio == 10) ? 1 : KERN_SUCCESS;
|
| -}
|
| -
|
| -struct exc_msg {
|
| - mach_msg_header_t header_;
|
| - NDR_record_t ndr_;
|
| - kern_return_t ret_code_;
|
| - char other_stuff[1024];
|
| -};
|
| -
|
| -namespace {
|
| -const int kMaxOutputDebugStringSize = 256;
|
| -const char kNexePrefix[] = "{7AA7C9CF-89EC-4ed3-8DAD-6DC84302AB11}";
|
| -} // namespace
|
| -
|
| -namespace debug {
|
| -DebugAPI::DebugAPI() : page_size_(0), exception_port_(0) {
|
| - vm_size_t ps = 0;
|
| - ::host_page_size(::mach_host_self(), &ps);
|
| - printf("page size = %d\n", ps);
|
| - page_size_ = ps;
|
| -}
|
| -
|
| -bool DebugAPI::StartProcess(const char* cmd_line,
|
| - bool trace,
|
| - pid_t* child_pid_out) {
|
| - pid_t child_pid = fork();
|
| - printf("fork -> %d\n", child_pid);
|
| - if (-1 == child_pid)
|
| - return false;
|
| -
|
| - if (0 == child_pid) {
|
| - // in child
|
| - if (trace) {
|
| - int res = ptrace(PT_TRACE_ME, 0, NULL, NULL);
|
| - printf("ptrace(PT_TRACE_ME, ... -> %d\n", res);
|
| - //ptrace(PT_SIGEXC, 0, NULL, NULL);
|
| - }
|
| - printf("calling execl (%s, ...)\n", cmd_line);
|
| -// int res = execl(cmd_line, "chrome", NULL);
|
| -// int res = execl(cmd_line, "chrome", "--disable-breakpad", "--incognito", "--no-sandbox", NULL);
|
| -// char* args[] = {"chrome", "--disable-breakpad", "--incognito", "--no-sandbox", NULL};
|
| - char* args[] = {"chrome", "--disable-breakpad", "--incognito", NULL};
|
| - char* envs[] = {/*"NACL_DANGEROUS_IGNORE_VALIDATOR=1", */NULL};
|
| - int res = execve(cmd_line, args, envs);
|
| -
|
| - printf("in child: execl -> %d errno=%d\n", res, errno);
|
| - exit(13);
|
| - } else {
|
| - // in parent
|
| - HookupDebugeeProcess(child_pid);
|
| -
|
| - if (NULL != child_pid_out)
|
| - *child_pid_out = child_pid;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -bool DebugAPI::HookupDebugeeProcess(pid_t pid) {
|
| - printf("DebugAPI::HookupRocess pid=%d\n", pid);
|
| - fflush(stdout);
|
| -
|
| - // Got the mach port for the current process
|
| - mach_port_t task_self = mach_task_self();
|
| -
|
| - mach_port_t target_task;
|
| - CALL_KERN(::task_for_pid(task_self, pid, &target_task));
|
| -
|
| - // Allocate an exception port that we will use to track our child process
|
| - CALL_KERN(::mach_port_allocate(task_self,
|
| - MACH_PORT_RIGHT_RECEIVE,
|
| - &exception_port_));
|
| -
|
| - // Add the ability to send messages on the new exception port
|
| - CALL_KERN(::mach_port_insert_right(task_self,
|
| - exception_port_,
|
| - exception_port_,
|
| - MACH_MSG_TYPE_MAKE_SEND));
|
| -
|
| - // Set the ability to get all exceptions from |target_task| on this port.
|
| - CALL_KERN(::task_set_exception_ports(
|
| - target_task,
|
| - EXC_MASK_BAD_ACCESS | EXC_MASK_BAD_INSTRUCTION | EXC_MASK_ARITHMETIC | EXC_MASK_BREAKPOINT | EXC_MASK_CRASH,
|
| - exception_port_,
|
| - EXCEPTION_DEFAULT,
|
| - THREAD_STATE_NONE));
|
| - return true;
|
| -}
|
| -
|
| -bool DebugAPI::WaitForMachException(int wait_ms, DebugEvent* de) {
|
| - if (0 == exception_port_)
|
| - return false;
|
| - //printf("DebugAPI::WaitForMachException(%d ms) exception_port_ = 0x%x\n", wait_ms, exception_port_);
|
| - //fflush(stdout);
|
| - bool event_received = false;
|
| - exc_msg msg_recv;
|
| - msg_recv.header_.msgh_local_port = exception_port_;
|
| - msg_recv.header_.msgh_size = sizeof(msg_recv);
|
| -
|
| - kern_return_t res = ::mach_msg(&msg_recv.header_,
|
| - MACH_RCV_MSG | MACH_RCV_LARGE | MACH_RCV_TIMEOUT,
|
| - 0, // send size
|
| - sizeof(msg_recv),
|
| - exception_port_,
|
| - wait_ms,
|
| - MACH_PORT_NULL); // no notify port
|
| - //printf("mach_msg -> %d\n", (int)res);
|
| - fflush(stdout);
|
| -
|
| - if (0 == res) {
|
| - printf("Got mach exception\n");
|
| - fflush(stdout);
|
| - glb_debug_event = de;
|
| - exc_msg msg_send;
|
| -
|
| - // It calls our catch_mach_exception_raise(),
|
| - // and it pauses the task (aka process).
|
| - exc_server(&msg_recv.header_, &msg_send.header_);
|
| - glb_debug_event = NULL;
|
| -
|
| - CALL_KERN2(::mach_msg(&(msg_send.header_),
|
| - MACH_SEND_MSG,
|
| - msg_send.header_.msgh_size,
|
| - 0,
|
| - MACH_PORT_NULL,
|
| - MACH_MSG_TIMEOUT_NONE,
|
| - MACH_PORT_NULL)); // no notify port
|
| - event_received = true;
|
| - if (2010 == de->signal_no_)
|
| - event_received = false;
|
| - }
|
| - //printf(" %s\n", event_received ? "new event" : "nothing");
|
| - //fflush(stdout);
|
| - return event_received;
|
| -}
|
| -
|
| -bool DebugAPI::WaitForDebugEvent(int wait_ms, DebugEvent* de) {
|
| - de->pid_ = 0;
|
| - de->signal_no_ = 0;
|
| - de->exit_code_ = 0;
|
| - de->process_state_ = PROCESS_STOPPED;
|
| -
|
| - int status = 0;
|
| - int options = WNOHANG | WUNTRACED | WCONTINUED;
|
| - int res = waitpid(-1, &status, options);
|
| - if ((-1 != res) && (0 != res)) {
|
| - de->pid_ = res;
|
| - if (WIFEXITED(status)) {
|
| - de->process_state_ = PROCESS_EXITED;
|
| - de->exit_code_ = WEXITSTATUS(status);
|
| - } else if (WIFSIGNALED(status)) {
|
| - de->process_state_ = PROCESS_TERMINATED;
|
| - de->signal_no_ = WTERMSIG(status);
|
| - } else if (WIFSTOPPED(status)) {
|
| - de->process_state_ = PROCESS_STOPPED;
|
| - de->signal_no_ = WSTOPSIG(status);
|
| - } else if (WIFCONTINUED(status)) {
|
| - de->process_state_ = PROCESS_STOPPED;
|
| - de->signal_no_ = 0;
|
| - }
|
| - return true;
|
| - }
|
| - return WaitForMachException(wait_ms, de);
|
| -}
|
| -
|
| -bool DebugAPI::PostSignal(pid_t pid, int signo) {
|
| - return (0 == kill(pid, signo));
|
| -}
|
| -
|
| -bool DebugAPI::ReadDebugString(const DebugEvent& de, std::string* string) {
|
| - if ((MACH_BREAKPOINT != de.signal_no_) || (PROCESS_STOPPED != de.process_state_))
|
| - return false;
|
| -
|
| - x86_thread_state context;
|
| - if (!ReadThreadContext(de.thread_, &context))
|
| - return false;
|
| -
|
| - uint64_t addr = context.uts.ts32.__eax;
|
| - char buff[kMaxOutputDebugStringSize];
|
| - size_t rd = 0;
|
| - ReadProcessMemory(de.pid_, addr, buff, sizeof(buff) - 1, &rd);
|
| - if (rd < sizeof(kNexePrefix))
|
| - return false;
|
| - if (strncmp(buff, kNexePrefix, sizeof(kNexePrefix) - 1) != 0)
|
| - return false;
|
| -
|
| - buff[sizeof(buff) - 1] = 0;
|
| - *string = &buff[sizeof(kNexePrefix) - 1];
|
| - printf("DebugString-[%s]\n", string->c_str());
|
| - return true;
|
| -}
|
| -
|
| -bool DebugAPI::ContinueDebugEvent(DebugEvent de, int signo) {
|
| - if (de.signal_no_ >= MACH_EXCEPTIONS_START_CODE) {
|
| - printf("Resuming task 0x%x", de.task_);
|
| - kern_return_t res = ::task_resume(de.task_);
|
| - printf("->%d\n", res);
|
| - //::mach_port_deallocate(::mach_host_self(), de.task_);
|
| - //::mach_port_deallocate(::mach_host_self(), de.thread_);
|
| - return (0 == res);
|
| - }
|
| - printf("calling ptrace(PTCONTINUE, %d, 1, %d)", de.pid_, signo);
|
| - ptrace_result_t res = ptrace(PT_CONTINUE, de.pid_, (char*)1, signo);
|
| - return (0 == res);
|
| -}
|
| -
|
| -bool DebugAPI::DebugBreak(pid_t pid) {
|
| - // TODO: really???
|
| - return PostSignal(pid, SIGSTOP);
|
| -}
|
| -
|
| -bool DebugAPI::SingleStep(DebugEvent de) {
|
| - // TODO: how we can single-step from mach exception?
|
| - //ptrace_result_t res = ptrace(PT_STEP, pid, 0, 0);
|
| - //return (0 == res);
|
| - return true;
|
| -}
|
| -
|
| -bool DebugAPI::ReadProcessMemory(pid_t pid,
|
| - uint64_t addr,
|
| - void* dest,
|
| - size_t size,
|
| - size_t* readed_bytes_out) {
|
| - mach_port_t target_task;
|
| - CALL_KERN(::task_for_pid(mach_task_self(), pid, &target_task));
|
| -// mach_vm_size_t rd = 0;
|
| -// CALL_KERN(::mach_vm_read_overwrite(target_task, (mach_vm_address_t)addr, size, (mach_vm_address_t)dest, &rd));
|
| -// if (NULL != readed_bytes_out)
|
| -// *readed_bytes_out = rd;
|
| -
|
| - uint64_t start_reg = vm_map_trunc_page(addr);
|
| - uint64_t reg_size = vm_map_round_page(size);
|
| - printf("start=0x%llx ", start_reg);
|
| - printf("reg_size=0x%llx ", reg_size);
|
| - uint64_t offset = addr - start_reg;
|
| - printf("roffset=0x%lld ", offset);
|
| -
|
| - //mach_vm_address_t address,
|
| - //mach_vm_size_t size,
|
| - vm_offset_t data = 0;
|
| - mach_msg_type_number_t dataCnt = 0;
|
| - kern_return_t res = ::mach_vm_read(target_task,
|
| - (mach_vm_size_t)start_reg,
|
| - (mach_vm_address_t)reg_size,
|
| - &data,
|
| - &dataCnt);
|
| - printf("mach_vm_read(0x%llx, %lld)-> res=%d, data=0x%p dataCnt=%d\n", start_reg, reg_size, res, (void*)data, dataCnt);
|
| - if (0 == res) {
|
| - memcpy(dest, (void*)(data + offset), size);
|
| - printf("mm1");
|
| - fflush(stdout);
|
| -
|
| - ::vm_deallocate(mach_task_self(), data, dataCnt);
|
| - printf("mm2\n");
|
| - fflush(stdout);
|
| - if (readed_bytes_out)
|
| - *readed_bytes_out = size;
|
| - printf("mm3\n");
|
| - fflush(stdout);
|
| -
|
| - return true;
|
| - }
|
| -
|
| - // TODO: shall we dealloc |target_task|?
|
| - return false;
|
| -}
|
| -
|
| -bool DebugAPI::WriteProcessMemory(pid_t pid,
|
| - uint64_t addr,
|
| - void* src,
|
| - size_t size,
|
| - size_t* written_bytes_out) {
|
| - printf("WrtMem: addr=0x%llx ", addr);
|
| - printf(" size=[%d]\n", (int)size);
|
| - mach_port_t target_task;
|
| - CALL_KERN(::task_for_pid(mach_task_self(), pid, &target_task));
|
| -
|
| - uint64_t start_reg = vm_map_trunc_page(addr);
|
| - uint64_t reg_size = vm_map_round_page(size);
|
| - printf("start=0x%llx ", start_reg);
|
| - printf("reg_size=0x%llx ", reg_size);
|
| - uint64_t offset = addr - start_reg;
|
| - char* buff = reinterpret_cast<char*>(malloc((size_t)reg_size));
|
| - size_t rd = 0;
|
| - bool rd_res = ReadProcessMemory(pid, start_reg, buff, (size_t)reg_size, &rd);
|
| - if (rd_res) {
|
| - memcpy(buff + offset, src, size);
|
| -
|
| - vm_address_t address = (int)start_reg;
|
| - vm_size_t ret_size = size;
|
| -
|
| - vm_region_basic_info info;
|
| - mach_msg_type_number_t infoCnt = sizeof(info) / sizeof(int);
|
| - mach_port_t object_name = 0;
|
| - kern_return_t res = ::vm_region(target_task,
|
| - &address,
|
| - &ret_size,
|
| - VM_REGION_BASIC_INFO,
|
| - (vm_region_info_t)&info,
|
| - &infoCnt,
|
| - &object_name);
|
| -
|
| -
|
| - printf("::vm_region(0x%X, 0x%X) -> res=%d prot=0x%X max_prot=0x%X\n",
|
| - (int)start_reg, (int)size, res, info.protection, info.max_protection);
|
| -
|
| - vm_prot_t new_protection = info.protection | VM_PROT_WRITE;
|
| - res = ::mach_vm_protect(target_task,
|
| - (mach_vm_address_t)start_reg,
|
| - (mach_vm_size_t)reg_size,
|
| - false,
|
| - new_protection);
|
| - printf("::mach_vm_protect-> %d\n", res);
|
| -
|
| - res = ::mach_vm_write(target_task, (int)start_reg, (vm_offset_t)buff, (int)reg_size);
|
| - printf ("::mach_vm_write-> %d\n", res);
|
| -
|
| - // Flush cashes.
|
| - //vm_machine_attribute_val_t flush_attr = MATTR_VAL_CACHE_FLUSH;
|
| - //res = ::vm_machine_attribute(target_task, (int)start_reg, (int)reg_size, MATTR_CACHE, &flush_attr);
|
| - //printf("::vm_machine_attribute -> %d\n", res);
|
| -
|
| - // Put back protection
|
| - res = ::mach_vm_protect(target_task,
|
| - (mach_vm_address_t)start_reg,
|
| - (mach_vm_size_t)reg_size,
|
| - false,
|
| - info.protection);
|
| - printf("::mach_vm_protect-> %d\n", res);
|
| - }
|
| - // TODO: shall we dealloc |target_task|? A: you can try & see what happens.
|
| - free(buff);
|
| - return true;
|
| -}
|
| -
|
| -bool DebugAPI::SetHwBreakpoint(int tid, uint64_t addr, int br_no) {
|
| - printf("DebugAPI::SetHwBreakpoint(tid=0x%x, addr=0x%llx, br_no=%d\n", tid, addr, br_no);
|
| - x86_debug_state32_t inf;
|
| - mach_msg_type_number_t buff_sz = x86_DEBUG_STATE32_COUNT; // in ints???
|
| - CALL_KERN(::thread_get_state(tid,
|
| - x86_DEBUG_STATE32,
|
| - reinterpret_cast<thread_state_t>(&inf),
|
| - &buff_sz));
|
| - printf("sz=%d\n", buff_sz);
|
| - switch (br_no) {
|
| - case 0: inf.__dr0 = (unsigned int)addr; break;
|
| - case 1: inf.__dr1 = (unsigned int)addr; break;
|
| - case 2: inf.__dr2 = (unsigned int)addr; break;
|
| - case 3: inf.__dr3 = (unsigned int)addr; break;
|
| - }
|
| - inf.__dr7 |= (1 << 9) + (1 << 8) + (1 << (br_no * 2));
|
| -
|
| - CALL_KERN(::thread_set_state(tid,
|
| - x86_DEBUG_STATE32,
|
| - reinterpret_cast<thread_state_t>(&inf),
|
| - buff_sz));
|
| - return true;
|
| -}
|
| -
|
| -
|
| -bool DebugAPI::ReadThreadContext(int tid, x86_thread_state* context) {
|
| -
|
| - mach_msg_type_number_t buff_sz = x86_THREAD_STATE_COUNT; // in ints???
|
| - CALL_KERN(::thread_get_state(tid,
|
| - x86_THREAD_STATE,
|
| - reinterpret_cast<thread_state_t>(context),
|
| - &buff_sz));
|
| - return true;
|
| -}
|
| -
|
| -/*
|
| - _STRUCT_X86_EXCEPTION_STATE32
|
| - {
|
| - unsigned int trapno;
|
| - unsigned int err;
|
| - unsigned int faultvaddr;
|
| - };
|
| - */
|
| -
|
| -
|
| -bool DebugAPI::WriteThreadContext(int tid, const x86_thread_state& context) {
|
| - mach_msg_type_number_t buff_sz = x86_THREAD_STATE_COUNT; // in ints???
|
| - CALL_KERN(::thread_set_state(tid,
|
| - x86_THREAD_STATE,
|
| - (thread_state_t)(&context),
|
| - buff_sz));
|
| - return true;
|
| -}
|
| -
|
| -bool DebugAPI::ReadIP(int tid, unsigned int* ip) {
|
| - x86_thread_state context;
|
| - memset(&context, 0, sizeof(context));
|
| - if (ReadThreadContext(tid, &context)) {
|
| - *ip = context.uts.ts32.__eip;
|
| - return true;
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool DebugAPI::WriteIP(int tid, unsigned int ip) {
|
| - x86_thread_state context;
|
| - memset(&context, 0, sizeof(context));
|
| - if (ReadThreadContext(tid, &context)) {
|
| - context.uts.ts32.__eip = ip;
|
| - return WriteThreadContext(tid, context);
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool DebugAPI::EnableSingleStep(int tid, bool enable) {
|
| - x86_thread_state context;
|
| - memset(&context, 0, sizeof(context));
|
| - if (ReadThreadContext(tid, &context)) {
|
| - uint32_t trace_bit = 0x100u;
|
| - uint32_t resume_bit = 0x10000u;
|
| - if (enable)
|
| - context.uts.ts32.__eflags |= trace_bit;
|
| - else
|
| - context.uts.ts32.__eflags &= ~trace_bit;
|
| - //context.uts.ts32.__eflags &= ~resume_bit;
|
| - return WriteThreadContext(tid, context);
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -bool DebugAPI::GetThreadList(pid_t pid, std::deque<int>* list) {
|
| - if (NULL == list)
|
| - return false;
|
| - list->clear();
|
| - mach_port_t target_task;
|
| - CALL_KERN(::task_for_pid(mach_task_self(), pid, &target_task));
|
| -
|
| - thread_array_t thread_list;
|
| - mach_msg_type_number_t thread_count = 0;
|
| - CALL_KERN(::task_threads(target_task, &thread_list, &thread_count));
|
| -
|
| - for (int i = 0; i < thread_count; i++) {
|
| - mach_port_t thread = thread_list[i];
|
| - list->push_back(thread);
|
| - ::mach_port_deallocate(mach_task_self(), thread);
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -#define AAA(x) case x: return #x
|
| -const char* GetSignalName(int signal_no) {
|
| - switch (signal_no) {
|
| - AAA(SIGHUP);
|
| - AAA(SIGINT);
|
| - AAA(SIGQUIT);
|
| - AAA(SIGILL);
|
| - AAA(SIGTRAP);
|
| - AAA(SIGABRT);
|
| - AAA(SIGEMT);
|
| - AAA(SIGFPE);
|
| - AAA(SIGKILL);
|
| - AAA(SIGBUS);
|
| - AAA(SIGSEGV);
|
| - AAA(SIGSYS);
|
| - AAA(SIGPIPE);
|
| - AAA(SIGALRM);
|
| - AAA(SIGTERM);
|
| - AAA(SIGURG);
|
| - AAA(SIGSTOP);
|
| - AAA(SIGTSTP);
|
| - AAA(SIGCONT);
|
| - AAA(SIGCHLD);
|
| - AAA(SIGTTIN);
|
| - AAA(SIGTTOU);
|
| - AAA(SIGIO);
|
| - AAA(SIGXCPU);
|
| - AAA(SIGXFSZ);
|
| - AAA(SIGVTALRM);
|
| - AAA(SIGPROF);
|
| - AAA(SIGWINCH);
|
| - AAA(SIGINFO);
|
| - AAA(SIGUSR1);
|
| - AAA(SIGUSR2);
|
| - AAA(MACH_BAD_ACCESS);
|
| - AAA(MACH_BAD_INSTRUCTION);
|
| - AAA(MACH_ARITHMETIC);
|
| - AAA(MACH_BREAKPOINT);
|
| - }
|
| - return "";
|
| -}
|
| -
|
| -const char* GetProcStateName(int process_state) {
|
| - switch (process_state) {
|
| - AAA(PROCESS_RUNNING);
|
| - AAA(PROCESS_STOPPED);
|
| - AAA(PROCESS_TERMINATED);
|
| - AAA(PROCESS_EXITED);
|
| - }
|
| - return "";
|
| -}
|
| -
|
| -void DebugEvent::Print() {
|
| - printf("\"DebugEvent\" : {\n");
|
| - printf("\t\"proc_state\" : \"%s\",\n", GetProcStateName(process_state_));
|
| - printf("\t\"pid_\" : \"0x%x\", \\%d\n", pid_, pid_);
|
| -
|
| - printf("\t\"signal_no_\" : \"%d\",", signal_no_);
|
| - if (0 != signal_no_)
|
| - printf(" //%s", GetSignalName(signal_no_));
|
| - printf("\n");
|
| -// if (child_pid_)
|
| -// printf("\t\"child_pid_\" : \"0x%x\",\n", child_pid_);
|
| -
|
| - printf("\t\"exit_code_\" : \"%d\",\n", exit_code_);
|
| - printf("\t\"task_\" : \"0x%x\",\n", task_);
|
| - printf("\t\"thread_\" : \"0x%x\",\n", thread_);
|
| - printf("}\n");
|
| -}
|
| -
|
| -} // namespace debug
|
| -
|
| -
|
| -//=========================================================================//
|
|
|