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

Unified Diff: experimental/mac_debugger/debug_api_mac.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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « experimental/mac_debugger/debug_api_mac.h ('k') | experimental/mac_debugger/debug_blob.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
-
-
-//=========================================================================//
« no previous file with comments | « experimental/mac_debugger/debug_api_mac.h ('k') | experimental/mac_debugger/debug_blob.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698