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

Side by Side Diff: experimental/windows_debugger/debugger/debug_server/debug_server.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 #include "debugger/debug_server/debug_server.h"
2 #include <assert.h>
3 #include <algorithm>
4 #include "debugger/core/debuggee_thread.h"
5 #include "debugger/core/debuggee_process.h"
6 #include "debugger/rsp/rsp_packet.h"
7 #include "debugger/core/debug_logger.h"
8
9 namespace {
10 const int kReadBufferSize = 1024;
11 const int kVS2008_THREAD_INFO = 0x406D1388;
12
13 void MakeContinueDecision(
14 const debug::DebugEvent& debug_event,
15 debug::DebuggeeThread* thread,
16 bool* halt,
17 bool* pass_exception);
18 rsp::StopReply GetStopReply(
19 debug::IDebuggeeProcess* halted_process);
20 int GetSignalNumber(const debug::DebugEvent& debug_event);
21
22 bool ExitedNormally(int ret_code) {
23 return ((ret_code >=0) && (ret_code < 256));
24 }
25 void PrintCONTEXT(const CONTEXT& ct);
26 } // namespace
27
28 namespace debug {
29 DebugServer::DebugServer()
30 : connection_was_established_(false),
31 focused_process_id_(0),
32 focused_thread_id_(0),
33 main_nexe_thread_id_(0) {
34 rsp_packetizer_.SetPacketConsumer(this);
35 execution_engine_ = new ExecutionEngine(&debug_api_);
36
37 #ifdef COMN_LOG
38 logger_ = Logger::Get();
39 #else
40 debug::TextFileLogger* log = new debug::TextFileLogger();
41 log->Open("nacl_gdbserver_log.txt");
42 log->EnableStdout(true);
43 logger_ = log;
44 #endif
45 }
46
47 DebugServer::~DebugServer() {
48 delete execution_engine_;
49 }
50
51 bool DebugServer::ListenOnPort(int port) {
52 bool res = listening_socket_.Listen(port);
53 if (res)
54 logger_->Log("TR100.1", "Started listening on port %d ...\n", port);
55 return res;
56 }
57
58 bool DebugServer::StartProcess(const char* cmd, const char* work_dir) {
59 bool res = execution_engine_->StartProcess(cmd, work_dir);
60 if (res)
61 logger_->Log("TR100.2", "Starting process [%s]...\n", cmd);
62 return res;
63 }
64
65 void DebugServer::DoWork(int wait_ms) {
66 if (!debugger_connection_.IsConnected()) {
67 if (connection_was_established_) {
68 connection_was_established_ = false;
69 logger_->Log("TR100.3", "Dropped connection from debugger.\n");
70 }
71 if (listening_socket_.Accept(&debugger_connection_, 0)) {
72 connection_was_established_ = true;
73 logger_->Log("TR100.4", "Got connection from debugger.\n");
74 }
75 } else {
76 char buff[kReadBufferSize];
77 for (int i = 0; i < 100; i++) {
78 size_t read_bytes = debugger_connection_.Read(buff,
79 sizeof(buff) - 1,
80 0);
81 if (read_bytes > 0) {
82 buff[read_bytes] = 0;
83 logger_->Log("R>", "[%s]\n", buff);
84 if (strncmp(buff, "+$Xc000206", 10) == 0)
85 printf("");
86
87 rsp_packetizer_.OnData(buff, read_bytes);
88 } else {
89 break;
90 }
91 }
92 }
93 int pid = 0;
94 execution_engine_->WaitForDebugEventAndDispatchIt(wait_ms, &pid);
95 IDebuggeeProcess* halted_process = execution_engine_->GetProcess(pid);
96 if (NULL != halted_process) {
97 if (debug::DebugEvent::kThreadIsAboutToStart ==
98 execution_engine_->debug_event().nacl_debug_event_code()) {
99 DebuggeeThread* thread = halted_process->GetHaltedThread();
100 if ((NULL != thread) && thread->IsNaClAppThread())
101 logger_->Log("TR100.5",
102 "NaClThreadStart mem_base=%p entry_point=%p thread_id=%d\n",
103 halted_process->nexe_mem_base(),
104 halted_process->nexe_entry_point(),
105 thread->id());
106 }
107
108 bool halt = false;
109 bool pass_exception = true;
110 MakeContinueDecision(execution_engine_->debug_event(),
111 halted_process->GetHaltedThread(),
112 &halt,
113 &pass_exception);
114 if (halt)
115 OnHaltedProcess(halted_process, execution_engine_->debug_event());
116 else if (pass_exception)
117 halted_process->ContinueAndPassExceptionToDebuggee();
118 else
119 halted_process->Continue();
120 }
121 }
122
123 void DebugServer::Quit() {
124 execution_engine_->Stop(300);
125 listening_socket_.Close();
126 debugger_connection_.Close();
127 }
128
129 void DebugServer::OnHaltedProcess(IDebuggeeProcess* halted_process,
130 const DebugEvent& debug_event) {
131 char tmp[1000];
132 debug_event.ToString(tmp, sizeof(tmp));
133 logger_->Log("TR100.6",
134 "Halted: pid=%d tid=%d\ndebugevent=%s\n",
135 halted_process->id(),
136 halted_process->GetHaltedThread()->id(),
137 tmp);
138
139 assert(halted_process->GetHaltedThread()->IsNaClAppThread());
140
141 // TODO: cleanup
142 CONTEXT ct;
143 halted_process->GetHaltedThread()->GetContext(&ct);
144 PrintCONTEXT(ct);
145
146 if (0 == main_nexe_thread_id_) {
147 focused_process_id_ = halted_process->id();
148 main_nexe_thread_id_ = focused_thread_id_;
149 }
150 focused_thread_id_ = halted_process->GetHaltedThread()->id();
151
152 if (debugger_connection_.IsConnected())
153 PostRspMessage(GetStopReply(halted_process));
154 }
155
156 void DebugServer::PostRspMessage(const rsp::Packet& msg) {
157 Blob text;
158 msg.ToBlob(&text);
159 Blob wire_msg;
160 rsp::PacketUtil::AddEnvelope(text, &wire_msg);
161 debugger_connection_.WriteAll(wire_msg);
162 logger_->Log("T>", "[%s]\n", text.ToString().c_str());
163 }
164
165 void DebugServer::OnUnknownCommand() {
166 PostRspMessage(rsp::EmptyPacket());
167 }
168
169 void DebugServer::OnPacket(const Blob& body, bool valid_checksum) {
170 if (valid_checksum)
171 debugger_connection_.WriteAll("+");
172
173 Blob msg = body;
174 rsp::Packet* command = rsp::Packet::CreateFromBlob(&msg);
175 if (NULL != command) {
176 command->AcceptVisitor(this);
177 delete command;
178 } else {
179 PostRspMessage(rsp::EmptyPacket());
180 }
181 }
182
183 void DebugServer::OnUnexpectedChar(char unexpected_char) {
184 logger_->Log("WARN21.01", "msg='DebugServer::OnUnexpectedChar' c='0x%x'", stat ic_cast<int>(unexpected_char));
185 }
186
187 void DebugServer::OnBreak() {
188 if (0 != focused_process_id_) {
189 //TODO : implement
190 OnUnknownCommand();
191 } else {
192 PostRspMessage(rsp::ErrorReply(1));
193 }
194 }
195
196 void DebugServer::Visit(rsp::GetStopReasonCommand* packet) {
197 IDebuggeeProcess* proc = execution_engine_->GetProcess(focused_process_id_);
198 if (NULL == proc) {
199 PostRspMessage(rsp::ErrorReply(2));
200 return;
201 }
202 DebugEvent debug_event = proc->last_debug_event();
203 DEBUG_EVENT wde = debug_event.windows_debug_event();
204 if (wde.dwDebugEventCode == EXIT_THREAD_DEBUG_EVENT) {
205 if (wde.dwThreadId == main_nexe_thread_id_) {
206 int ret_code = wde.u.ExitThread.dwExitCode;
207 if (ExitedNormally(ret_code)) {
208 rsp::StopReply reply(rsp::StopReply::EXITED);
209 reply.set_exit_code(ret_code);
210 PostRspMessage(reply);
211 } else {
212 rsp::StopReply reply(rsp::StopReply::TERMINATED);
213 reply.set_signal_number(ret_code);
214 PostRspMessage(reply);
215 }
216 return;
217 }
218 }
219 if (proc->IsHalted())
220 PostRspMessage(GetStopReply(proc));
221 else if (DebuggeeProcess::kDead == proc->state())
222 PostRspMessage(rsp::ErrorReply(5));
223 else // Process is running.
224 PostRspMessage(rsp::StopReply(rsp::StopReply::STILL_RUNNING));
225 }
226
227 void DebugServer::Visit(rsp::ContinueCommand* packet) {
228 IDebuggeeProcess* proc = execution_engine_->GetProcess(focused_process_id_);
229 if (NULL == proc)
230 PostRspMessage(rsp::ErrorReply(4));
231 else
232 proc->Continue();
233 }
234
235 void DebugServer::Visit(rsp::QuerySupportedCommand* packet) {
236 rsp::QuerySupportedReply reply;
237 reply.AddFeature("PacketSize", "7cf");
238 reply.AddFeature("qXfer:libraries:read", "+");
239 reply.AddFeature("qXfer:features:read", "+");
240 PostRspMessage(reply);
241 }
242
243 void DebugServer::Visit(rsp::QXferFeaturesReadCommand* packet) {
244 //qXfer:features:read:target.xml:0,7ca
245 if (packet->file_name() == "target.xml") {
246 rsp::QXferReply reply;
247 reply.set_body("<target><architecture>i386:x86-64</architecture></target>");
248 reply.set_eom(true);
249 PostRspMessage(reply);
250 } else {
251 OnUnknownCommand();
252 }
253 }
254
255 void DebugServer::Visit(rsp::SetCurrentThreadCommand* packet) {
256 int tid = static_cast<int>(packet->thread_id());
257 bool res = false;
258 if (-1 == tid) { // all threads
259 res = false;
260 } else if (0 == tid) { // any thread
261 res = true;
262 } else {
263 IDebuggeeProcess* proc = execution_engine_->GetProcess(focused_process_id_);
264 if (NULL != proc) {
265 DebuggeeThread* thread = proc->GetThread(tid);
266 if (NULL != thread) {
267 res = true;
268 focused_thread_id_ = tid;
269 }
270 }
271 }
272 if (res)
273 PostRspMessage(rsp::OkReply());
274 else
275 PostRspMessage(rsp::ErrorReply(3));
276 }
277
278 void DebugServer::Visit(rsp::ReadMemoryCommand* packet) {
279 int sz = packet->num_of_bytes();
280 if (0 == sz) {
281 PostRspMessage(rsp::ErrorReply(4));
282 return;
283 }
284 // We advertize max size of RSP packet as 1999
285 char buff[3000];
286 if (sizeof(buff) < sz) {
287 PostRspMessage(rsp::ErrorReply(5));
288 return;
289 }
290 IDebuggeeProcess* proc = execution_engine_->GetProcess(focused_process_id_);
291 if (NULL != proc) {
292 char* addr = reinterpret_cast<char*>(packet->addr());
293 // massage address to support gdb
294 if (addr < proc->nexe_mem_base())
295 addr += reinterpret_cast<size_t>(proc->nexe_mem_base());
296
297 if (proc->ReadMemory(addr, sz, buff)) {
298 rsp::BlobReply reply;
299 reply.set_data(buff, sz);
300 PostRspMessage(reply);
301 } else {
302 PostRspMessage(rsp::ErrorReply(6));
303 }
304 } else {
305 PostRspMessage(rsp::ErrorReply(7));
306 }
307 }
308
309 void DebugServer::Visit(rsp::WriteMemoryCommand* packet) {
310 const debug::Blob& data = packet->data();
311 IDebuggeeProcess* proc = execution_engine_->GetProcess(focused_process_id_);
312 if (NULL != proc) {
313 void* tmp = data.ToCBuffer();
314 if (NULL == tmp) {
315 PostRspMessage(rsp::ErrorReply(8));
316 return;
317 }
318
319 char* addr = reinterpret_cast<char*>(packet->addr());
320 // massage address to support gdb
321 if (addr < proc->nexe_mem_base())
322 addr += reinterpret_cast<size_t>(proc->nexe_mem_base());
323
324 bool res = proc->WriteMemory(addr, data.size(), tmp);
325 free(tmp);
326 if (res)
327 PostRspMessage(rsp::OkReply());
328 else
329 PostRspMessage(rsp::ErrorReply(9));
330 } else {
331 logger_->Log("WARN21.02", "Can't find process pid=%d", focused_process_id_);
332 PostRspMessage(rsp::ErrorReply(10));
333 }
334 }
335
336 void DebugServer::Visit(rsp::ReadRegistersCommand* packet) {
337 Blob registers_blob;
338 if (ReadGdbRegisters(&registers_blob)) {
339 rsp::BlobReply reply;
340 reply.set_data(registers_blob);
341 PostRspMessage(reply);
342 } else {
343 logger_->Log("WARN21.03", "DebugServer::ReadGdbRegisters pid=%d tid=%d -> fa lse", focused_process_id_, focused_thread_id_);
344 PostRspMessage(rsp::ErrorReply(113));
345 }
346 }
347
348 void DebugServer::Visit(rsp::WriteRegistersCommand* packet) {
349 IDebuggeeProcess* proc = execution_engine_->GetProcess(focused_process_id_);
350 if (NULL == proc) {
351 PostRspMessage(rsp::ErrorReply(14));
352 return;
353 }
354 DebuggeeThread* thread = proc->GetThread(focused_thread_id_);
355 if (NULL == thread) {
356 PostRspMessage(rsp::ErrorReply(15));
357 return;
358 }
359 CONTEXT ct;
360 if (!thread->GetContext(&ct)) {
361 PostRspMessage(rsp::ErrorReply(16));
362 return;
363 }
364 GdbRegistersToCONTEXT(packet->data(), &ct);
365 if (!thread->SetContext(ct))
366 PostRspMessage(rsp::ErrorReply(16));
367 else
368 PostRspMessage(rsp::OkReply());
369 }
370
371 #define X86_32_REGS \
372 REG(Eax); \
373 REG(Ecx); \
374 REG(Edx); \
375 REG(Ebx); \
376 REG(Esp); \
377 REG(Ebp); \
378 REG(Esi); \
379 REG(Edi); \
380 REG(Eip); \
381 REG(EFlags); \
382 REG(SegCs); \
383 REG(SegSs); \
384 REG(SegDs); \
385 REG(SegEs); \
386 REG(SegFs); \
387 REG(SegGs)
388
389 #define X86_64_REGS \
390 REG(Rax); \
391 REG(Rbx); \
392 REG(Rcx); \
393 REG(Rdx); \
394 REG(Rsi); \
395 REG(Rdi); \
396 REG(Rbp); \
397 REG(Rsp); \
398 REG(R8); \
399 REG(R9); \
400 REG(R10); \
401 REG(R11); \
402 REG(R12); \
403 REG(R13); \
404 REG(R14); \
405 REG(R15); \
406 REG(Rip); \
407 REG(EFlags); \
408 REG(SegCs); \
409 REG(SegSs); \
410 REG(SegDs); \
411 REG(SegEs); \
412 REG(SegFs); \
413 REG(SegGs)
414
415 char* names_of_bad_regs = "EFlags,SegCs,SegSs,SegDs,SegEs,SegFs,SegGs,";
416
417 size_t WriteReg(const Blob& blob, size_t offset, void* dst, int reg_size, const char* name) {
418 char* pp = strstr(names_of_bad_regs,name);
419 size_t name_len = strlen(name);
420 if ((NULL != pp) && (',' == *(pp + name_len))) {
421 unsigned long reg = 0;
422 reg_size = sizeof(reg);
423 blob.Peek(offset, &reg, sizeof(reg));
424 memcpy(dst, &reg, 2);
425 } else {
426 blob.Peek(offset, dst, reg_size);
427 }
428 return offset + reg_size;
429 }
430
431 void DebugServer::GdbRegistersToCONTEXT(const Blob& gdb_regs, CONTEXT* ct) {
432 size_t offset = 0;
433 #define REG(name) ct->name = 0; offset = WriteReg(gdb_regs, offset, &ct->name, s izeof(ct->name), #name)
434 #ifdef _WIN64
435 X86_64_REGS;
436 #else
437 X86_32_REGS;
438 #endif
439 #undef REG
440 }
441
442 void ReadReg(Blob* blob, void* src, int reg_size, const char* name) {
443 char* pp = strstr(names_of_bad_regs,name);
444 size_t name_len = strlen(name);
445 if ((NULL != pp) && (',' == *(pp + name_len))) {
446 unsigned long reg = 0;
447 memcpy(&reg, src, 2);
448 blob->Append(Blob(&reg, sizeof(reg)));
449 } else {
450 blob->Append(Blob(src, reg_size));
451 }
452 }
453
454 bool DebugServer::ReadGdbRegisters(Blob* blob) {
455 IDebuggeeProcess* proc = execution_engine_->GetProcess(focused_process_id_);
456 if (NULL == proc) {
457 logger_->Log("WARN21.05", "Can't find process pid=%d", focused_process_id_);
458 return false;
459 }
460
461 DebuggeeThread* thread = proc->GetThread(focused_thread_id_);
462 if (NULL == thread) {
463 logger_->Log("WARN21.06", "Can't find thread pid=%d tid=%d", focused_process _id_, focused_thread_id_);
464 return false;
465 }
466
467 CONTEXT ct;
468 if (!thread->GetContext(&ct)) {
469 logger_->Log("WARN21.07", "thread->GetContext failed. pid=%d tid=%d", focuse d_process_id_, focused_thread_id_);
470 return false;
471 }
472
473 #define REG(name) ReadReg(blob, &ct.name, sizeof(ct.name), #name)
474 #ifdef _WIN64
475 X86_64_REGS;
476 #else
477 X86_32_REGS;
478 #endif
479 #undef REG
480
481 logger_->Log("TRACE21.08", "DebugServer::ReadGdbRegisters pid=%d tid=%d -> tru e", focused_process_id_, focused_thread_id_);
482 return true;
483 }
484
485 void DebugServer::Visit(rsp::GetCurrentThreadCommand* packet) {
486 rsp::GetCurrentThreadReply reply;
487 reply.set_value(focused_thread_id_);
488 PostRspMessage(reply);
489 }
490
491 void DebugServer::Visit(rsp::StepCommand* packet) {
492 IDebuggeeProcess* proc = execution_engine_->GetProcess(focused_process_id_);
493 if (NULL == proc)
494 PostRspMessage(rsp::ErrorReply(20));
495 else if (!proc->SingleStep())
496 PostRspMessage(rsp::ErrorReply(21));
497 }
498
499 void DebugServer::Visit(rsp::IsThreadAliveCommand* packet) {
500 IDebuggeeProcess* proc = execution_engine_->GetProcess(focused_process_id_);
501 if (NULL == proc) {
502 PostRspMessage(rsp::ErrorReply(22));
503 return;
504 }
505 std::deque<int> tids;
506 proc->GetThreadIds(&tids);
507 if (std::find(tids.begin(), tids.end(), packet->value()) != tids.end()) {
508 PostRspMessage(rsp::OkReply());
509 // found it
510 } else {
511 PostRspMessage(rsp::ErrorReply(23)); // TODO: make error codes declared con stants
512 }
513 }
514
515 void DebugServer::Visit(rsp::GetThreadInfoCommand* packet) {
516 IDebuggeeProcess* proc = execution_engine_->GetProcess(focused_process_id_);
517 if (NULL == proc) {
518 PostRspMessage(rsp::ErrorReply(24));
519 return;
520 }
521 rsp::GetThreadInfoReply reply;
522 if (packet->get_more()) {
523 reply.set_eom(true); // TODO(garianov): add support for multy packet replie s.
524 } else {
525 std::deque<int> tids;
526 proc->GetThreadIds(&tids);
527
528 std::deque<int> nexe_tids;
529 for (size_t i = 0; i < tids.size(); i++) {
530 int tid = tids[i];
531 DebuggeeThread* thread = proc->GetThread(tid);
532 if ((NULL != thread) && (thread->IsNaClAppThread()))
533 nexe_tids.push_back(tid);
534 }
535 reply.set_threads_ids(nexe_tids);
536 reply.set_eom(false);
537 }
538 PostRspMessage(reply);
539 }
540
541 } // namespace debug
542
543 namespace {
544 void MakeContinueDecision(
545 const debug::DebugEvent& debug_event,
546 debug::DebuggeeThread* thread,
547 bool* halt,
548 bool* pass_exception) {
549 if (OUTPUT_DEBUG_STRING_EVENT == debug_event.windows_debug_event().dwDebugEven tCode) {
550 *halt = false;
551 *pass_exception = false;
552 }
553
554 if (debug::DebugEvent::kNotNaClDebugEvent != debug_event.nacl_debug_event_code ()) {
555 *halt = true;
556 return;
557 }
558 int exception_code = debug_event.windows_debug_event().u.Exception.ExceptionRe cord.ExceptionCode;
559
560 if (EXCEPTION_DEBUG_EVENT == debug_event.windows_debug_event().dwDebugEventCod e) {
561 if (kVS2008_THREAD_INFO == exception_code) {
562 *halt = false;
563 } else {
564 bool is_nexe = false;
565 if (NULL != thread)
566 is_nexe = thread->IsNaClAppThread();
567
568 if (is_nexe)
569 printf("");
570
571 *pass_exception = true;
572
573 if (EXCEPTION_BREAKPOINT == exception_code)
574 *pass_exception = false;
575
576 if (is_nexe) {
577 *halt = true;
578 } else {
579 *halt = false;
580 }
581 }
582 }
583 }
584
585 rsp::StopReply GetStopReply(debug::IDebuggeeProcess* halted_process) {
586 debug::DebugEvent debug_event = halted_process->last_debug_event();
587 DEBUG_EVENT wde = debug_event.windows_debug_event();
588
589 int exception_code = wde.u.Exception.ExceptionRecord.ExceptionCode;
590 switch (wde.dwDebugEventCode) {
591 case CREATE_PROCESS_DEBUG_EVENT:
592 case CREATE_THREAD_DEBUG_EVENT:
593 case EXCEPTION_DEBUG_EVENT:
594 case LOAD_DLL_DEBUG_EVENT:
595 case OUTPUT_DEBUG_STRING_EVENT:
596 case EXIT_THREAD_DEBUG_EVENT:
597 case UNLOAD_DLL_DEBUG_EVENT: {
598 rsp::StopReply reply(rsp::StopReply::SIGNALED);
599 reply.set_signal_number(GetSignalNumber(debug_event));
600 return reply;
601 }
602 case RIP_EVENT: {
603 rsp::StopReply reply(rsp::StopReply::TERMINATED);
604 reply.set_signal_number(GetSignalNumber(debug_event));
605 return reply;
606 }
607 case EXIT_PROCESS_DEBUG_EVENT: {
608 // NaClAppThread terminated or exited:
609 int ret_code = wde.u.ExitThread.dwExitCode;
610 if (ExitedNormally(ret_code)) {
611 rsp::StopReply reply(rsp::StopReply::EXITED);
612 reply.set_exit_code(ret_code);
613 return reply;
614 } else {
615 rsp::StopReply reply(rsp::StopReply::TERMINATED);
616 reply.set_signal_number(ret_code);
617 return reply;
618 }
619 }
620 }
621 return rsp::StopReply::SIGNALED;
622 }
623
624 int GetSignalNumber(const debug::DebugEvent& debug_event) {
625 const int SIGSEGV = 11;
626 const int SIGSYS = 31;
627 const int SIGTRAP = 5;
628 const int SIGBUS = 7;
629 const int SIGFPE = 8;
630 const int SIGILL = 4;
631 const int SIGINT = 2;
632 const int SIGSTOP = 19;
633
634 switch (debug_event.windows_debug_event().dwDebugEventCode) {
635 case CREATE_PROCESS_DEBUG_EVENT:
636 case CREATE_THREAD_DEBUG_EVENT:
637 case LOAD_DLL_DEBUG_EVENT:
638 case OUTPUT_DEBUG_STRING_EVENT:
639 case UNLOAD_DLL_DEBUG_EVENT:
640 case EXIT_THREAD_DEBUG_EVENT:
641 case EXIT_PROCESS_DEBUG_EVENT:
642 return SIGSTOP;
643
644 case EXCEPTION_DEBUG_EVENT: {
645 switch (debug_event.windows_debug_event().u.Exception.ExceptionRecord.Exce ptionCode) {
646 case EXCEPTION_ACCESS_VIOLATION:
647 case EXCEPTION_STACK_OVERFLOW:
648 return SIGSEGV;
649 case EXCEPTION_BREAKPOINT:
650 case EXCEPTION_SINGLE_STEP:
651 return SIGTRAP;
652
653 case EXCEPTION_DATATYPE_MISALIGNMENT: return SIGBUS;
654
655 case EXCEPTION_FLT_DENORMAL_OPERAND:
656 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
657 case EXCEPTION_FLT_INEXACT_RESULT:
658 case EXCEPTION_FLT_INVALID_OPERATION:
659 case EXCEPTION_FLT_OVERFLOW:
660 case EXCEPTION_FLT_STACK_CHECK:
661 case EXCEPTION_FLT_UNDERFLOW:
662 case EXCEPTION_INT_DIVIDE_BY_ZERO:
663 case EXCEPTION_INT_OVERFLOW:
664 return SIGFPE;
665
666 case EXCEPTION_ILLEGAL_INSTRUCTION:
667 case EXCEPTION_PRIV_INSTRUCTION:
668 return SIGILL;
669 case DBG_CONTROL_C: return SIGINT;
670 }
671 }
672 }
673 return SIGSYS;
674 }
675
676 void PrintCONTEXT(const CONTEXT& ct) {
677 printf("CONTEXT = {\n");
678 #define REG(name) printf("\t%s=0x%x\n", #name, ct.name)
679 #ifdef _WIN64
680 X86_64_REGS;
681 #else
682 X86_32_REGS;
683 #endif
684 #undef REG
685 printf("}\n");
686 }
687
688 } // namespace
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698