blob: de0821eb4253068e71ed02dbce1ceabe011767d5 [file] [log] [blame]
Greg Claytonf4b47e12010-08-04 01:40:35 +00001//===-- StopInfoMachException.cpp -------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "StopInfoMachException.h"
11
Jason Molendaff6a4ed2018-11-10 00:25:45 +000012
13#if defined(__APPLE__)
14// Needed for the EXC_RESOURCE interpretation macros
Jason Molendaa9796ed2018-11-10 00:14:14 +000015#include <kern/exc_resource.h>
Jason Molendaff6a4ed2018-11-10 00:25:45 +000016#endif
Jason Molendaa9796ed2018-11-10 00:14:14 +000017
Johnny Chen01a67862011-10-14 00:42:25 +000018#include "lldb/Breakpoint/Watchpoint.h"
Greg Clayton90ba8112012-12-05 00:16:59 +000019#include "lldb/Symbol/Symbol.h"
20#include "lldb/Target/DynamicLoader.h"
Greg Clayton1ac04c32012-02-21 00:09:25 +000021#include "lldb/Target/ExecutionContext.h"
Greg Claytonf4b47e12010-08-04 01:40:35 +000022#include "lldb/Target/Process.h"
23#include "lldb/Target/RegisterContext.h"
24#include "lldb/Target/Target.h"
25#include "lldb/Target/Thread.h"
26#include "lldb/Target/ThreadPlan.h"
27#include "lldb/Target/UnixSignals.h"
Zachary Turnerbf9a7732017-02-02 21:39:50 +000028#include "lldb/Utility/StreamString.h"
Greg Claytonf4b47e12010-08-04 01:40:35 +000029
30using namespace lldb;
31using namespace lldb_private;
Greg Claytonf4b47e12010-08-04 01:40:35 +000032
Kate Stoneb9c1b512016-09-06 20:57:50 +000033const char *StopInfoMachException::GetDescription() {
34 if (m_description.empty() && m_value != 0) {
35 ExecutionContext exe_ctx(m_thread_wp.lock());
36 Target *target = exe_ctx.GetTargetPtr();
37 const llvm::Triple::ArchType cpu =
38 target ? target->GetArchitecture().GetMachine()
39 : llvm::Triple::UnknownArch;
Greg Claytonf4b47e12010-08-04 01:40:35 +000040
Kate Stoneb9c1b512016-09-06 20:57:50 +000041 const char *exc_desc = NULL;
42 const char *code_label = "code";
43 const char *code_desc = NULL;
44 const char *subcode_label = "subcode";
45 const char *subcode_desc = NULL;
Jason Molendaa9796ed2018-11-10 00:14:14 +000046
Alexander Kornienko87ab8f32018-11-12 13:41:42 +000047#if defined(__APPLE__)
Jason Molendaa9796ed2018-11-10 00:14:14 +000048 char code_desc_buf[32];
49 char subcode_desc_buf[32];
Alexander Kornienko87ab8f32018-11-12 13:41:42 +000050#endif
Jason Molendaa9796ed2018-11-10 00:14:14 +000051
Kate Stoneb9c1b512016-09-06 20:57:50 +000052 switch (m_value) {
53 case 1: // EXC_BAD_ACCESS
54 exc_desc = "EXC_BAD_ACCESS";
55 subcode_label = "address";
56 switch (cpu) {
57 case llvm::Triple::x86:
58 case llvm::Triple::x86_64:
59 switch (m_exc_code) {
60 case 0xd:
61 code_desc = "EXC_I386_GPFLT";
62 m_exc_data_count = 1;
63 break;
64 }
65 break;
66 case llvm::Triple::arm:
67 case llvm::Triple::thumb:
68 switch (m_exc_code) {
69 case 0x101:
70 code_desc = "EXC_ARM_DA_ALIGN";
71 break;
72 case 0x102:
73 code_desc = "EXC_ARM_DA_DEBUG";
74 break;
75 }
76 break;
Greg Claytonf4b47e12010-08-04 01:40:35 +000077
Kate Stoneb9c1b512016-09-06 20:57:50 +000078 case llvm::Triple::ppc:
79 case llvm::Triple::ppc64:
80 switch (m_exc_code) {
81 case 0x101:
82 code_desc = "EXC_PPC_VM_PROT_READ";
83 break;
84 case 0x102:
85 code_desc = "EXC_PPC_BADSPACE";
86 break;
87 case 0x103:
88 code_desc = "EXC_PPC_UNALIGNED";
89 break;
90 }
91 break;
Greg Claytonf4b47e12010-08-04 01:40:35 +000092
Kate Stoneb9c1b512016-09-06 20:57:50 +000093 default:
94 break;
95 }
96 break;
Greg Claytonf4b47e12010-08-04 01:40:35 +000097
Kate Stoneb9c1b512016-09-06 20:57:50 +000098 case 2: // EXC_BAD_INSTRUCTION
99 exc_desc = "EXC_BAD_INSTRUCTION";
100 switch (cpu) {
101 case llvm::Triple::x86:
102 case llvm::Triple::x86_64:
103 if (m_exc_code == 1)
104 code_desc = "EXC_I386_INVOP";
105 break;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000106
Kate Stoneb9c1b512016-09-06 20:57:50 +0000107 case llvm::Triple::ppc:
108 case llvm::Triple::ppc64:
109 switch (m_exc_code) {
110 case 1:
111 code_desc = "EXC_PPC_INVALID_SYSCALL";
112 break;
113 case 2:
114 code_desc = "EXC_PPC_UNIPL_INST";
115 break;
116 case 3:
117 code_desc = "EXC_PPC_PRIVINST";
118 break;
119 case 4:
120 code_desc = "EXC_PPC_PRIVREG";
121 break;
122 case 5:
123 code_desc = "EXC_PPC_TRACE";
124 break;
125 case 6:
126 code_desc = "EXC_PPC_PERFMON";
127 break;
128 }
129 break;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000130
Kate Stoneb9c1b512016-09-06 20:57:50 +0000131 case llvm::Triple::arm:
132 case llvm::Triple::thumb:
133 if (m_exc_code == 1)
134 code_desc = "EXC_ARM_UNDEFINED";
135 break;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000136
Kate Stoneb9c1b512016-09-06 20:57:50 +0000137 default:
138 break;
139 }
140 break;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000141
Kate Stoneb9c1b512016-09-06 20:57:50 +0000142 case 3: // EXC_ARITHMETIC
143 exc_desc = "EXC_ARITHMETIC";
144 switch (cpu) {
145 case llvm::Triple::x86:
146 case llvm::Triple::x86_64:
147 switch (m_exc_code) {
148 case 1:
149 code_desc = "EXC_I386_DIV";
150 break;
151 case 2:
152 code_desc = "EXC_I386_INTO";
153 break;
154 case 3:
155 code_desc = "EXC_I386_NOEXT";
156 break;
157 case 4:
158 code_desc = "EXC_I386_EXTOVR";
159 break;
160 case 5:
161 code_desc = "EXC_I386_EXTERR";
162 break;
163 case 6:
164 code_desc = "EXC_I386_EMERR";
165 break;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000166 case 7:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000167 code_desc = "EXC_I386_BOUND";
168 break;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000169 case 8:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000170 code_desc = "EXC_I386_SSEEXTERR";
171 break;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000172 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000173 break;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000174
Kate Stoneb9c1b512016-09-06 20:57:50 +0000175 case llvm::Triple::ppc:
176 case llvm::Triple::ppc64:
177 switch (m_exc_code) {
178 case 1:
179 code_desc = "EXC_PPC_OVERFLOW";
180 break;
181 case 2:
182 code_desc = "EXC_PPC_ZERO_DIVIDE";
183 break;
184 case 3:
185 code_desc = "EXC_PPC_FLT_INEXACT";
186 break;
187 case 4:
188 code_desc = "EXC_PPC_FLT_ZERO_DIVIDE";
189 break;
190 case 5:
191 code_desc = "EXC_PPC_FLT_UNDERFLOW";
192 break;
193 case 6:
194 code_desc = "EXC_PPC_FLT_OVERFLOW";
195 break;
196 case 7:
197 code_desc = "EXC_PPC_FLT_NOT_A_NUMBER";
198 break;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000199 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000200 break;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000201
Kate Stoneb9c1b512016-09-06 20:57:50 +0000202 default:
203 break;
204 }
205 break;
206
207 case 4: // EXC_EMULATION
208 exc_desc = "EXC_EMULATION";
209 break;
210
211 case 5: // EXC_SOFTWARE
212 exc_desc = "EXC_SOFTWARE";
213 if (m_exc_code == 0x10003) {
214 subcode_desc = "EXC_SOFT_SIGNAL";
215 subcode_label = "signo";
216 }
217 break;
218
219 case 6: // EXC_BREAKPOINT
220 {
221 exc_desc = "EXC_BREAKPOINT";
222 switch (cpu) {
223 case llvm::Triple::x86:
224 case llvm::Triple::x86_64:
225 switch (m_exc_code) {
226 case 1:
227 code_desc = "EXC_I386_SGL";
228 break;
229 case 2:
230 code_desc = "EXC_I386_BPT";
231 break;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000232 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000233 break;
234
235 case llvm::Triple::ppc:
236 case llvm::Triple::ppc64:
237 switch (m_exc_code) {
238 case 1:
239 code_desc = "EXC_PPC_BREAKPOINT";
240 break;
241 }
242 break;
243
244 case llvm::Triple::arm:
245 case llvm::Triple::thumb:
246 switch (m_exc_code) {
247 case 0x101:
248 code_desc = "EXC_ARM_DA_ALIGN";
249 break;
250 case 0x102:
251 code_desc = "EXC_ARM_DA_DEBUG";
252 break;
253 case 1:
254 code_desc = "EXC_ARM_BREAKPOINT";
255 break;
256 // FIXME temporary workaround, exc_code 0 does not really mean
257 // EXC_ARM_BREAKPOINT
258 case 0:
259 code_desc = "EXC_ARM_BREAKPOINT";
260 break;
261 }
262 break;
263
264 default:
265 break;
266 }
267 } break;
268
269 case 7:
270 exc_desc = "EXC_SYSCALL";
271 break;
272
273 case 8:
274 exc_desc = "EXC_MACH_SYSCALL";
275 break;
276
277 case 9:
278 exc_desc = "EXC_RPC_ALERT";
279 break;
280
281 case 10:
282 exc_desc = "EXC_CRASH";
283 break;
284 case 11:
285 exc_desc = "EXC_RESOURCE";
Jason Molendaff6a4ed2018-11-10 00:25:45 +0000286#if defined(__APPLE__)
Jason Molendaa9796ed2018-11-10 00:14:14 +0000287 {
288 int resource_type = EXC_RESOURCE_DECODE_RESOURCE_TYPE(m_exc_code);
289
290 code_label = "limit";
291 code_desc = code_desc_buf;
292 subcode_label = "observed";
293 subcode_desc = subcode_desc_buf;
294
295 switch (resource_type) {
296 case RESOURCE_TYPE_CPU:
297 exc_desc = "EXC_RESOURCE RESOURCE_TYPE_CPU";
298 snprintf(code_desc_buf, sizeof(code_desc_buf), "%d%%",
299 (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE(m_exc_code));
300 snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d%%",
301 (int)EXC_RESOURCE_CPUMONITOR_DECODE_PERCENTAGE_OBSERVED(m_exc_subcode));
302 break;
303 case RESOURCE_TYPE_WAKEUPS:
304 exc_desc = "EXC_RESOURCE RESOURCE_TYPE_WAKEUPS";
305 snprintf(code_desc_buf, sizeof(code_desc_buf), "%d w/s",
306 (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_PERMITTED(m_exc_code));
307 snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d w/s",
308 (int)EXC_RESOURCE_CPUMONITOR_DECODE_WAKEUPS_OBSERVED(m_exc_subcode));
309 break;
310 case RESOURCE_TYPE_MEMORY:
311 exc_desc = "EXC_RESOURCE RESOURCE_TYPE_MEMORY";
312 snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB",
313 (int)EXC_RESOURCE_HWM_DECODE_LIMIT(m_exc_code));
314 subcode_desc = nullptr;
315 subcode_label = "unused";
316 break;
317 case RESOURCE_TYPE_IO:
318 exc_desc = "EXC_RESOURCE RESOURCE_TYPE_IO";
319 snprintf(code_desc_buf, sizeof(code_desc_buf), "%d MB",
320 (int)EXC_RESOURCE_IO_DECODE_LIMIT(m_exc_code));
321 snprintf(subcode_desc_buf, sizeof(subcode_desc_buf), "%d MB",
322 (int)EXC_RESOURCE_IO_OBSERVED(m_exc_subcode));;
323 break;
324 }
325 }
Jason Molendaff6a4ed2018-11-10 00:25:45 +0000326#endif
Kate Stoneb9c1b512016-09-06 20:57:50 +0000327 break;
328 case 12:
329 exc_desc = "EXC_GUARD";
330 break;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000331 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000332
333 StreamString strm;
334
335 if (exc_desc)
336 strm.PutCString(exc_desc);
337 else
338 strm.Printf("EXC_??? (%" PRIu64 ")", m_value);
339
340 if (m_exc_data_count >= 1) {
341 if (code_desc)
342 strm.Printf(" (%s=%s", code_label, code_desc);
343 else
344 strm.Printf(" (%s=%" PRIu64, code_label, m_exc_code);
345 }
346
347 if (m_exc_data_count >= 2) {
348 if (subcode_desc)
349 strm.Printf(", %s=%s", subcode_label, subcode_desc);
350 else
351 strm.Printf(", %s=0x%" PRIx64, subcode_label, m_exc_subcode);
352 }
353
354 if (m_exc_data_count > 0)
355 strm.PutChar(')');
356
Zachary Turnerc1564272016-11-16 21:15:24 +0000357 m_description = strm.GetString();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000358 }
359 return m_description.c_str();
Greg Claytonf4b47e12010-08-04 01:40:35 +0000360}
361
Kate Stoneb9c1b512016-09-06 20:57:50 +0000362StopInfoSP StopInfoMachException::CreateStopReasonWithMachException(
363 Thread &thread, uint32_t exc_type, uint32_t exc_data_count,
364 uint64_t exc_code, uint64_t exc_sub_code, uint64_t exc_sub_sub_code,
365 bool pc_already_adjusted, bool adjust_pc_if_needed) {
366 if (exc_type != 0) {
367 uint32_t pc_decrement = 0;
368 ExecutionContext exe_ctx(thread.shared_from_this());
369 Target *target = exe_ctx.GetTargetPtr();
370 const llvm::Triple::ArchType cpu =
371 target ? target->GetArchitecture().GetMachine()
372 : llvm::Triple::UnknownArch;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000373
Kate Stoneb9c1b512016-09-06 20:57:50 +0000374 switch (exc_type) {
375 case 1: // EXC_BAD_ACCESS
376 break;
Greg Clayton97d5cf02012-09-25 02:40:06 +0000377
Kate Stoneb9c1b512016-09-06 20:57:50 +0000378 case 2: // EXC_BAD_INSTRUCTION
379 switch (cpu) {
380 case llvm::Triple::ppc:
381 case llvm::Triple::ppc64:
382 switch (exc_code) {
383 case 1: // EXC_PPC_INVALID_SYSCALL
384 case 2: // EXC_PPC_UNIPL_INST
385 case 3: // EXC_PPC_PRIVINST
386 case 4: // EXC_PPC_PRIVREG
387 break;
388 case 5: // EXC_PPC_TRACE
389 return StopInfo::CreateStopReasonToTrace(thread);
390 case 6: // EXC_PPC_PERFMON
391 break;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000392 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000393 break;
394
395 default:
396 break;
397 }
398 break;
399
400 case 3: // EXC_ARITHMETIC
401 case 4: // EXC_EMULATION
402 break;
403
404 case 5: // EXC_SOFTWARE
405 if (exc_code == 0x10003) // EXC_SOFT_SIGNAL
406 {
407 if (exc_sub_code == 5) {
Adrian Prantl05097242018-04-30 16:49:04 +0000408 // On MacOSX, a SIGTRAP can signify that a process has called exec,
409 // so we should check with our dynamic loader to verify.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000410 ProcessSP process_sp(thread.GetProcess());
411 if (process_sp) {
412 DynamicLoader *dynamic_loader = process_sp->GetDynamicLoader();
413 if (dynamic_loader && dynamic_loader->ProcessDidExec()) {
414 // The program was re-exec'ed
415 return StopInfo::CreateStopReasonWithExec(thread);
416 }
417 // if (!process_did_exec)
418 // {
419 // // We have a SIGTRAP, make sure we
420 // didn't exec by checking
421 // // for the PC being at
422 // "_dyld_start"...
423 // lldb::StackFrameSP frame_sp
424 // (thread.GetStackFrameAtIndex(0));
425 // if (frame_sp)
426 // {
427 // const Symbol *symbol =
428 // frame_sp->GetSymbolContext(eSymbolContextSymbol).symbol;
429 // if (symbol)
430 // {
431 // if (symbol->GetName() ==
432 // ConstString("_dyld_start"))
433 // process_did_exec = true;
434 // }
435 // }
436 // }
437 }
438 }
439 return StopInfo::CreateStopReasonWithSignal(thread, exc_sub_code);
440 }
441 break;
442
443 case 6: // EXC_BREAKPOINT
444 {
445 bool is_actual_breakpoint = false;
446 bool is_trace_if_actual_breakpoint_missing = false;
447 switch (cpu) {
448 case llvm::Triple::x86:
449 case llvm::Triple::x86_64:
450 if (exc_code == 1) // EXC_I386_SGL
451 {
452 if (!exc_sub_code) {
453 // This looks like a plain trap.
454 // Have to check if there is a breakpoint here as well. When you
Adrian Prantl05097242018-04-30 16:49:04 +0000455 // single-step onto a trap, the single step stops you not to trap.
456 // Since we also do that check below, let's just use that logic.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000457 is_actual_breakpoint = true;
458 is_trace_if_actual_breakpoint_missing = true;
459 } else {
460
461 // It's a watchpoint, then.
462 // The exc_sub_code indicates the data break address.
463 lldb::WatchpointSP wp_sp;
464 if (target)
465 wp_sp = target->GetWatchpointList().FindByAddress(
466 (lldb::addr_t)exc_sub_code);
467 if (wp_sp && wp_sp->IsEnabled()) {
468 // Debugserver may piggyback the hardware index of the fired
Adrian Prantl05097242018-04-30 16:49:04 +0000469 // watchpoint in the exception data. Set the hardware index if
470 // that's the case.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000471 if (exc_data_count >= 3)
472 wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
473 return StopInfo::CreateStopReasonWithWatchpointID(thread,
474 wp_sp->GetID());
475 }
476 }
477 } else if (exc_code == 2 || // EXC_I386_BPT
478 exc_code == 3) // EXC_I386_BPTFLT
479 {
480 // KDP returns EXC_I386_BPTFLT for trace breakpoints
481 if (exc_code == 3)
482 is_trace_if_actual_breakpoint_missing = true;
483
484 is_actual_breakpoint = true;
485 if (!pc_already_adjusted)
486 pc_decrement = 1;
487 }
488 break;
489
490 case llvm::Triple::ppc:
491 case llvm::Triple::ppc64:
492 is_actual_breakpoint = exc_code == 1; // EXC_PPC_BREAKPOINT
493 break;
494
495 case llvm::Triple::arm:
496 case llvm::Triple::thumb:
497 if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
498 {
499 // It's a watchpoint, then, if the exc_sub_code indicates a
Adrian Prantl05097242018-04-30 16:49:04 +0000500 // known/enabled data break address from our watchpoint list.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000501 lldb::WatchpointSP wp_sp;
502 if (target)
503 wp_sp = target->GetWatchpointList().FindByAddress(
504 (lldb::addr_t)exc_sub_code);
505 if (wp_sp && wp_sp->IsEnabled()) {
506 // Debugserver may piggyback the hardware index of the fired
Adrian Prantl05097242018-04-30 16:49:04 +0000507 // watchpoint in the exception data. Set the hardware index if
508 // that's the case.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000509 if (exc_data_count >= 3)
510 wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
511 return StopInfo::CreateStopReasonWithWatchpointID(thread,
512 wp_sp->GetID());
513 } else {
514 is_actual_breakpoint = true;
515 is_trace_if_actual_breakpoint_missing = true;
516 }
517 } else if (exc_code == 1) // EXC_ARM_BREAKPOINT
518 {
519 is_actual_breakpoint = true;
520 is_trace_if_actual_breakpoint_missing = true;
521 } else if (exc_code == 0) // FIXME not EXC_ARM_BREAKPOINT but a kernel
Adrian Prantl05097242018-04-30 16:49:04 +0000522 // is currently returning this so accept it
523 // as indicating a breakpoint until the
524 // kernel is fixed
Kate Stoneb9c1b512016-09-06 20:57:50 +0000525 {
526 is_actual_breakpoint = true;
527 is_trace_if_actual_breakpoint_missing = true;
528 }
529 break;
530
531 case llvm::Triple::aarch64: {
532 if (exc_code == 1 && exc_sub_code == 0) // EXC_ARM_BREAKPOINT
533 {
534 // This is hit when we single instruction step aka MDSCR_EL1 SS bit 0
535 // is set
536 is_actual_breakpoint = false;
537 is_trace_if_actual_breakpoint_missing = true;
538 }
539 if (exc_code == 0x102) // EXC_ARM_DA_DEBUG
540 {
541 // It's a watchpoint, then, if the exc_sub_code indicates a
Adrian Prantl05097242018-04-30 16:49:04 +0000542 // known/enabled data break address from our watchpoint list.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000543 lldb::WatchpointSP wp_sp;
544 if (target)
545 wp_sp = target->GetWatchpointList().FindByAddress(
546 (lldb::addr_t)exc_sub_code);
547 if (wp_sp && wp_sp->IsEnabled()) {
548 // Debugserver may piggyback the hardware index of the fired
Adrian Prantl05097242018-04-30 16:49:04 +0000549 // watchpoint in the exception data. Set the hardware index if
550 // that's the case.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000551 if (exc_data_count >= 3)
552 wp_sp->SetHardwareIndex((uint32_t)exc_sub_sub_code);
553 return StopInfo::CreateStopReasonWithWatchpointID(thread,
554 wp_sp->GetID());
555 }
556 // EXC_ARM_DA_DEBUG seems to be reused for EXC_BREAKPOINT as well as
557 // EXC_BAD_ACCESS
558 if (thread.GetTemporaryResumeState() == eStateStepping)
559 return StopInfo::CreateStopReasonToTrace(thread);
560 }
561 // It looks like exc_sub_code has the 4 bytes of the instruction that
Adrian Prantl05097242018-04-30 16:49:04 +0000562 // triggered the exception, i.e. our breakpoint opcode
Kate Stoneb9c1b512016-09-06 20:57:50 +0000563 is_actual_breakpoint = exc_code == 1;
564 break;
565 }
566
567 default:
568 break;
569 }
570
571 if (is_actual_breakpoint) {
572 RegisterContextSP reg_ctx_sp(thread.GetRegisterContext());
573 addr_t pc = reg_ctx_sp->GetPC() - pc_decrement;
574
575 ProcessSP process_sp(thread.CalculateProcess());
576
577 lldb::BreakpointSiteSP bp_site_sp;
578 if (process_sp)
579 bp_site_sp = process_sp->GetBreakpointSiteList().FindByAddress(pc);
580 if (bp_site_sp && bp_site_sp->IsEnabled()) {
Adrian Prantl05097242018-04-30 16:49:04 +0000581 // Update the PC if we were asked to do so, but only do so if we find
582 // a breakpoint that we know about cause this could be a trap
583 // instruction in the code
Kate Stoneb9c1b512016-09-06 20:57:50 +0000584 if (pc_decrement > 0 && adjust_pc_if_needed)
585 reg_ctx_sp->SetPC(pc);
586
587 // If the breakpoint is for this thread, then we'll report the hit,
Adrian Prantl05097242018-04-30 16:49:04 +0000588 // but if it is for another thread, we can just report no reason. We
589 // don't need to worry about stepping over the breakpoint here, that
Kate Stoneb9c1b512016-09-06 20:57:50 +0000590 // will be taken care of when the thread resumes and notices that
Adrian Prantl05097242018-04-30 16:49:04 +0000591 // there's a breakpoint under the pc. If we have an operating system
592 // plug-in, we might have set a thread specific breakpoint using the
Kate Stoneb9c1b512016-09-06 20:57:50 +0000593 // operating system thread ID, so we can't make any assumptions about
Adrian Prantl05097242018-04-30 16:49:04 +0000594 // the thread ID so we must always report the breakpoint regardless
595 // of the thread.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000596 if (bp_site_sp->ValidForThisThread(&thread) ||
597 thread.GetProcess()->GetOperatingSystem() != NULL)
598 return StopInfo::CreateStopReasonWithBreakpointSiteID(
599 thread, bp_site_sp->GetID());
600 else if (is_trace_if_actual_breakpoint_missing)
601 return StopInfo::CreateStopReasonToTrace(thread);
602 else
603 return StopInfoSP();
604 }
605
606 // Don't call this a trace if we weren't single stepping this thread.
607 if (is_trace_if_actual_breakpoint_missing &&
608 thread.GetTemporaryResumeState() == eStateStepping) {
609 return StopInfo::CreateStopReasonToTrace(thread);
610 }
611 }
612 } break;
613
614 case 7: // EXC_SYSCALL
615 case 8: // EXC_MACH_SYSCALL
616 case 9: // EXC_RPC_ALERT
617 case 10: // EXC_CRASH
618 break;
Greg Claytonf4b47e12010-08-04 01:40:35 +0000619 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000620
621 return StopInfoSP(new StopInfoMachException(
622 thread, exc_type, exc_data_count, exc_code, exc_sub_code));
623 }
624 return StopInfoSP();
Greg Claytonf4b47e12010-08-04 01:40:35 +0000625}