Index: experimental/mac_debugger/debugger.cc |
diff --git a/experimental/mac_debugger/debugger.cc b/experimental/mac_debugger/debugger.cc |
deleted file mode 100644 |
index f657af4d0bad58df399455ef1471c39fb1ce85b3..0000000000000000000000000000000000000000 |
--- a/experimental/mac_debugger/debugger.cc |
+++ /dev/null |
@@ -1,512 +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 <fcntl.h> |
- |
-#ifndef _WIN32 |
-#include <sys/types.h> |
-#include <pthread.h> |
-#include <signal.h> |
-#include <termios.h> |
-#include <unistd.h> |
-#include <mach/mach_vm.h> |
-#include <mach/mach.h> |
-#else |
-#include <conio.h> |
-#pragma warning(disable : 4996 4267 4244 4800 4101) |
-#define snprintf _snprintf |
-#endif |
- |
-#include <stdio.h> |
-#include <stdlib.h> |
-#include <string.h> |
- |
-#include <deque> |
-#include <string> |
-#include <map> |
- |
-#include "debug_api_mac.h" |
-#include "debug_blob.h" |
-#include "debug_command_line.h" |
- |
-extern "C" kern_return_t catch_exception_raise(mach_port_t exception_port, |
- mach_port_t thread, |
- mach_port_t task, |
- exception_type_t exception, |
- exception_data_t code, |
- mach_msg_type_number_t code_count); |
-void* atoptr(const char* str) { |
- void* ptr = 0; |
- sscanf(str, "%p", &ptr); // NOLINT |
- return ptr; |
-} |
- |
-uint64_t glb_mem_base = 0; |
- |
-struct Breakpoint { |
- Breakpoint() : addr_(0), instr_length_(0), id_(0), ip_(0) {} |
- Breakpoint(uint64_t ip, int instr_length) : ip_(ip), addr_(ip + glb_mem_base), instr_length_(instr_length) { |
- id_ = next_id_; |
- next_id_ = ++next_id_ % 4; |
- } |
- |
- uint64_t addr_; |
- int instr_length_; |
- int id_; |
- int ip_; |
- static int next_id_; |
-}; |
- |
-int Breakpoint::next_id_ = 0; |
- |
-std::map<uint64_t, Breakpoint> glb_breakpoints; |
-uint64_t glb_continue_from_br_addr = 0; |
- |
-#ifndef _WIN32 |
-int kbhit() { |
- termios oldt; |
- tcgetattr(STDIN_FILENO, &oldt); |
- termios newt = oldt; |
- newt.c_lflag &= ~(ICANON | ECHO); |
- tcsetattr(STDIN_FILENO, TCSANOW, &newt); |
- int oldf = fcntl(STDIN_FILENO, F_GETFL, 0); |
- fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK); |
- |
- int ch = getchar(); |
- |
- tcsetattr(STDIN_FILENO, TCSANOW, &oldt); |
- fcntl(STDIN_FILENO, F_SETFL, oldf); |
- |
- if (EOF != ch) { |
- ungetc(ch, stdin); |
- return 1; |
- } |
- return 0; |
-} |
-#endif |
- |
-void Split(const char* str_in, |
- const char* delimiters, |
- std::deque<std::string>* out) { |
- char c = 0; |
- std::string str; |
- while (c = *str_in++) { |
- if (strchr(delimiters, c)) { |
- if (str.size()) { |
- out->push_back(str); |
- str.clear(); |
- } |
- } else if ((c != '\r') && (c != '\n')) { |
- str.push_back(c); |
- } |
- } |
- if (str.size()) |
- out->push_back(str); |
-} |
- |
-void printList(const std::deque<std::string>& list) { |
- printf("list {\n"); |
- size_t num = list.size(); |
- for (size_t i = 0; i < num; i++) |
- printf("[%s]\n", list[i].c_str()); |
- printf("}\n"); |
-} |
- |
-int main(int argc, char *argv[]) { |
- printf("Version 0.006 Build: %s %s\n", __DATE__, __TIME__); |
- debug::DebugAPI deb_api; |
- pid_t child_pid = 0; |
- |
- // catch_exception_raise(0, 0, 0, 0, 0, 0); |
- |
- const char* cmd = "/Users/garianov/Documents/chromium/src/xcodebuild/Release/Chromium.app/Contents/MacOS/Chromium"; |
-#define CHROMEEE |
-#ifdef CHROMEEE |
- bool sp_res = deb_api.StartProcess( |
- //"/Applications/Google Chrome.app/Contents/MacOS/Google Chrome", |
- cmd, |
- true, |
- &child_pid); |
-#else |
- cmd = "../../../test/build/Debug/test"; |
- bool sp_res = deb_api.StartProcess( |
- cmd, |
- true, |
- &child_pid); |
-#endif |
- |
- printf("Process [%s] %s. Pid = 0x%x == %d\n", cmd, sp_res ? "started" : "failed to start", child_pid, child_pid); |
- |
- bool show_events = true; |
- int nacl_pid = 0; |
- bool animate = false; |
- FILE* file = fopen("anim.txt", "wt"); |
- bool first = true; |
-#ifdef CHROMEEE |
- static bool iterative = true; //false; |
-#else |
- static bool iterative = true; |
-#endif |
- |
- while (true) { |
- if (kbhit()) { |
- char buff[100] = { 0 }; |
- fgets(buff, sizeof(buff) -1, stdin); |
- |
- std::deque<std::string> words; |
- Split(buff, " \t", &words); |
- printList(words); |
- if (words.size() ==0) |
- continue; |
- if ((words[0] == "break") && (words.size() >= 2)) { |
- int pid = atoi(words[1].c_str()); |
- bool res = deb_api.DebugBreak(pid); |
- if (!res) |
- printf("Error\n"); |
- continue; |
- } else if ((words[0] == "H") && (words.size() >= 2)) { |
- int pid = atoi(words[1].c_str()); |
- deb_api.HookupDebugeeProcess(pid); |
- |
- } else if ((words[0] == "h") && (words.size() >= 2)) { |
- int pid = atoi(words[1].c_str()); |
- |
- mach_port_t target_task; |
- int res = 0; |
- if (0 != (res = ::task_for_pid(mach_task_self(), pid, &target_task))) { |
- printf("task_for_pid(%d) -> %d\n", pid, res); |
- } else { |
- const int kMaxExcNum = 20; |
- exception_mask_t masks[kMaxExcNum]; |
- mach_msg_type_number_t masksCnt = kMaxExcNum; |
- mach_port_t ports[kMaxExcNum]; |
- exception_behavior_t bhv[kMaxExcNum]; |
- thread_state_flavor_t flv[kMaxExcNum]; |
- res = ::task_get_exception_ports(target_task, EXC_MASK_ALL, masks, &masksCnt, ports, bhv, flv); |
- if (0 == res) { |
- printf("%d ports\n", masksCnt); |
- for (int i = 0; i < masksCnt; i++) { |
- printf("port=0x%x mask=0x%x\n", ports[i], masks[i]); |
- } |
- } else { |
- printf("task_get_exception_ports -> %d\n", res); |
- } |
- } |
- } else if (words[0] == "e-") { |
- printf("show_events = false\n"); |
- show_events = false; |
- continue; |
- } |
- } |
- |
- bool do_continue = false; |
- debug::DebugEvent de; |
- if (deb_api.WaitForDebugEvent(1000, &de)) { |
- if (de.signal_no_ == MACH_BREAKPOINT) { |
- // OutputDebugString? |
- std::string msg; |
- if (deb_api.ReadDebugString(de, &msg)) { |
- // parse it |
- debug::CommandLine debug_info(msg); |
- std::string event = debug_info.GetStringSwitch("-event", ""); |
- if ("AppCreate" == event) { |
- void* mem_base = debug_info.GetAddrSwitch("-mem_start"); |
- void* user_entry_point = debug_info.GetAddrSwitch("-user_entry_pt"); |
- printf("NaClAppCreate mem_base=%p entry_point=%p\n", |
- mem_base, |
- user_entry_point); |
- glb_mem_base = (uint64_t)mem_base; |
- deb_api.ContinueDebugEvent(de, 0); |
- continue; |
- } |
- } |
- |
- unsigned int ip = 0; |
- if (!deb_api.ReadIP(de.thread_, &ip)) { |
- printf("Error reading ip\n"); |
- } else { |
- if (0 != glb_continue_from_br_addr) { |
- printf("Continuing from or breakpoint at 0x%llx\n", glb_continue_from_br_addr); |
- Breakpoint br = glb_breakpoints[glb_continue_from_br_addr]; |
- glb_continue_from_br_addr = 0; |
- deb_api.SetHwBreakpoint(de.thread_, br.addr_, br.id_); |
- deb_api.ContinueDebugEvent(de, 0); |
- continue; |
- } |
- } |
- } |
- |
- if (0) { //debug::DebugEvent::OUTPUT_DEBUG_STRING == de.event_code_) { |
- iterative = true; |
- nacl_pid = de.pid_; |
- printf("Got OUTPUT_DEBUG_STRING: "); |
- std::string string; |
- if (deb_api.ReadDebugString(de, &string)) |
- printf("[%s]", string.c_str()); |
- printf("\n"); |
-// deb_api.ContinueDebugEvent(de.pid_); |
-// do_continue = true; |
- } |
- |
- //if (show_events || (nacl_pid == de.pid_) || |
- // (SIGTRAP == de.signal_no_)) |
- de.Print(); |
- |
- if (animate && (nacl_pid == de.pid_) && |
- (SIGTRAP == de.signal_no_)) { |
- printf("SIGTRAP == de.signal_no_\n"); |
- fflush(file); |
-// deb_api.EnableSingleStep(de.pid_, false); |
-// deb_api.SingleStep(nacl_pid); |
- continue; |
- } |
- |
- while (!do_continue) { |
- char buff[100] = { 0 }; |
- |
- if (iterative) { |
- printf("\n[%d]>", de.pid_); |
- fflush(stdout); |
- fgets(buff, sizeof(buff) -1, stdin); |
- } else { |
- snprintf(buff, sizeof(buff), "c"); |
- } |
- // test only: end |
- |
- static bool first = true; |
- if (first) { |
- first = false; |
-// deb_api.SetupProc(de.pid_); |
- } |
- |
- std::deque<std::string> words; |
- Split(buff, " \t", &words); |
-// printList(words); |
- if (words.size() < 1) |
- continue; |
- if (words[0] == "c") { |
- if (de.signal_no_ == MACH_BREAKPOINT) { |
- unsigned int ip = 0; |
- if (!deb_api.ReadIP(de.thread_, &ip)) { |
- printf("Error reading ip\n"); |
- } else if (glb_breakpoints.end() != glb_breakpoints.find(ip)) { |
- printf("Our breakpoint hit at 0x%x\n", ip); |
- Breakpoint br = glb_breakpoints[ip]; |
- glb_continue_from_br_addr = br.ip_; |
- deb_api.SetHwBreakpoint(de.thread_, br.addr_ + br.instr_length_, br.id_); |
- deb_api.ContinueDebugEvent(de, 0); |
- break; |
- } |
- } |
- int signo = de.signal_no_; |
- if (signo == SIGTRAP) |
- signo = 0; |
- deb_api.ContinueDebugEvent(de, 0); |
- break; |
- } else if (words[0] == "e-") { |
- printf("show_events = false\n"); |
- show_events = false; |
- continue; |
- } else if (words[0] == "ce") { |
-// deb_api.EnableSingleStep(de.pid_, false); |
- deb_api.ContinueDebugEvent(de, de.signal_no_); |
- break; |
- } else if (words[0] == "cn") { |
-// deb_api.EnableSingleStep(de.pid_, false); |
- deb_api.ContinueDebugEvent(de, 0); |
- break; |
- } else if (words[0] == "si") { |
- deb_api.EnableSingleStep(de.thread_, true); |
- // deb_api.ContinueDebugEvent(de, 0); |
- printf("si %d\n", de.pid_); |
- // deb_api.SingleStep(de.pid_); |
- // break; |
- } else if (words[0] == "si-") { |
- deb_api.EnableSingleStep(de.thread_, false); |
- printf("si- %d\n", de.pid_); |
- } else if (words[0] == "cb") { |
- // continue and break immediately |
-// deb_api.EnableSingleStep(de.pid_, false); |
- deb_api.ContinueDebugEvent(de, 0); |
- bool res = deb_api.DebugBreak(de.pid_); |
- if (!res) |
- printf("Error\n"); |
- break; |
- } else if (words[0] == "th") { |
- mach_port_t target_thread =de.thread_; |
- const int kMaxExcNum = 20; |
- exception_mask_t masks[kMaxExcNum]; |
- mach_msg_type_number_t masksCnt = kMaxExcNum; |
- mach_port_t ports[kMaxExcNum]; |
- exception_behavior_t bhv[kMaxExcNum]; |
- thread_state_flavor_t flv[kMaxExcNum]; |
- int res = ::thread_get_exception_ports(target_thread, EXC_MASK_ALL, masks, &masksCnt, ports, bhv, flv); |
- if (0 == res) { |
- printf("%d ports\n", masksCnt); |
- for (int i = 0; i < masksCnt; i++) { |
- printf("port=0x%x mask=0x%x\n", ports[i], masks[i]); |
- } |
- } else { |
- printf("task_get_exception_ports -> %d\n", res); |
- } |
- } else if (words[0] == "h") { |
- mach_port_t target_task = de.task_; |
- int res = 0; |
- const int kMaxExcNum = 20; |
- exception_mask_t masks[kMaxExcNum]; |
- mach_msg_type_number_t masksCnt = kMaxExcNum; |
- mach_port_t ports[kMaxExcNum]; |
- exception_behavior_t bhv[kMaxExcNum]; |
- thread_state_flavor_t flv[kMaxExcNum]; |
- res = ::task_get_exception_ports(target_task, EXC_MASK_ALL, masks, &masksCnt, ports, bhv, flv); |
- if (0 == res) { |
- printf("%d ports\n", masksCnt); |
- for (int i = 0; i < masksCnt; i++) { |
- printf("port=0x%x mask=0x%x\n", ports[i], masks[i]); |
- } |
- } else { |
- printf("task_get_exception_ports -> %d\n", res); |
- } |
- } else if ((words[0] == "at") && (words.size() >= 2)) { |
- int pid = atoi(words[1].c_str()); |
- int res = ptrace(PT_ATTACHEXC, pid, 0, 0); |
- printf("attach to %d -> %d\n", pid, res); |
- |
- } else if ((words[0] == "m") && (words.size() >= 3)) { |
- uint64_t addr = 0; |
- sscanf(words[1].c_str(), "%llx", &addr); |
- printf("addr:0x%llx\n", addr); |
- int len = atoi(words[2].c_str()); |
- size_t rd = 0; |
- char buff[1024]; |
- bool res = deb_api.ReadProcessMemory(de.pid_, |
- addr, |
- buff, |
- len, |
- &rd); |
- if (res) { |
- printf("ReadProcessMemory -> %ld\n", rd); |
- fflush(stdout); |
- debug::Blob blob(buff, rd); |
- printf("zz1\n"); |
- fflush(stdout); |
- std::string str = blob.ToHexString(false); |
- printf("zz2\n"); |
- fflush(stdout); |
- printf("[%s]\n", str.c_str()); |
- printf("zz3\n"); |
- fflush(stdout); |
- } else { |
- printf("Error\n"); |
- } |
- } else if ((words[0] == "M") && (words.size() >= 3)) { |
- uint64_t addr = 0; //atoi(words[1].c_str()); |
- sscanf(words[1].c_str(), "%llx", &addr); |
- printf("addr:0x%llx\n", addr); |
- debug::Blob blob; |
- blob.LoadFromHexString(words[2]); |
- |
- void* data = blob.ToCBuffer(); |
- debug::Blob blob2(data, blob.Size()); |
- std::string str = blob2.ToHexString(false); |
- printf("recv[%s] sz=%d\n", str.c_str(), blob.Size()); |
- |
- if (NULL != data) { |
- size_t wr = 0; |
- int sz = blob.Size(); |
- printf(" sz = %d\n", sz); |
- bool res = deb_api.WriteProcessMemory(de.pid_, |
- addr, |
- data, |
- sz, |
- &wr); |
- if (!res) |
- printf("Error\n"); |
- free(data); |
- } |
- } else if ((words[0] == "mem_base") && (words.size() >= 2)) { |
- uint64_t addr = 0; //atoi(words[1].c_str()); |
- sscanf(words[1].c_str(), "%llx", &addr); |
- glb_mem_base = addr; |
- } else if ((words[0] == "br") && (words.size() > 2)) { |
- uint64_t ip = 0; //atoi(words[1].c_str()); |
- sscanf(words[1].c_str(), "%llx", &ip); |
- int len = atoi(words[2].c_str()); |
- printf("ip:0x%llx\n", ip); |
- Breakpoint br(ip, len); |
- glb_breakpoints[ip] = br; |
- |
- deb_api.SetHwBreakpoint(de.thread_, br.addr_, br.id_); |
- |
- |
- } else if (words[0] == "g") { |
- x86_thread_state context; |
- memset(&context, 0, sizeof(context)); |
- bool res = deb_api.ReadThreadContext(de.thread_, &context); |
- if (res) { |
- printf("tsh = %d\n", context.tsh.flavor); |
- if (context.tsh.flavor == x86_THREAD_STATE32) { |
-#define AAS(x) printf("\t%s = 0x%x\n", #x, context.uts.ts32.__##x) |
- AAS(eax); |
- AAS(ebx); |
- AAS(ecx); |
- AAS(edx); |
- AAS(edi); |
- AAS(esi); |
- AAS(ebp); |
- AAS(esp); |
- AAS(ss); |
- AAS(eflags); |
- AAS(eip); |
- AAS(cs); |
- AAS(ds); |
- AAS(es); |
- AAS(fs); |
- AAS(gs); |
- |
- } |
- } |
- } else if (words[0] == "ip") { |
- unsigned int ip = 0; |
- deb_api.ReadIP(de.thread_, &ip); |
- printf("IP = 0x%x\n", ip); |
- } else if (words[0] == "ip--") { |
- unsigned int ip = 0; |
- if (deb_api.ReadIP(de.thread_, &ip)) { |
- ip--; |
- deb_api.WriteIP(de.thread_, ip); |
- printf("IP = 0x%x\n", ip); |
- } |
- } else if (words[0] == "ip++") { |
- unsigned int ip = 0; |
- if (deb_api.ReadIP(de.thread_, &ip)) { |
- ip++; |
- deb_api.WriteIP(de.thread_, ip); |
- printf("IP = 0x%x\n", ip); |
- } |
- } else if ((words[0] == "break") && (words.size() >= 2)) { |
- int pid = atoi(words[2].c_str()); |
- bool res = deb_api.DebugBreak(pid); |
- if (!res) |
- printf("Error\n"); |
- } |
- } |
- } |
- } |
- return 1; |
-} |
- |
-/* |
-#include "debugger_front_end.h" |
-#include "debugger_back_end.h" |
- |
-int main2(int argc, char *argv[]) { |
- debug::BackEnd back_end; |
- debug::FrontEnd debugger(&back_end); |
- int ret_code = 0; |
- if (!debugger.Init(argc, argv, &ret_code)) |
- return ret_code; |
- |
- return debugger.Run(); |
-} |
-*/ |