Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(8)

Side by Side Diff: src/client/mac/handler/minidump_generator.cc

Issue 307002: Allow minidump generator to generate ARM minidumps (for iOS on a device). (Closed) Base URL: http://google-breakpad.googlecode.com/svn/trunk/
Patch Set: Created 13 years, 5 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2006, Google Inc. 1 // Copyright (c) 2006, Google Inc.
2 // All rights reserved. 2 // All rights reserved.
3 // 3 //
4 // Redistribution and use in source and binary forms, with or without 4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are 5 // modification, are permitted provided that the following conditions are
6 // met: 6 // met:
7 // 7 //
8 // * Redistributions of source code must retain the above copyright 8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer. 9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above 10 // * Redistributions in binary form must reproduce the above
(...skipping 13 matching lines...) Expand all
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 29
30 #include <algorithm> 30 #include <algorithm>
31 #include <cstdio> 31 #include <cstdio>
32 32
33 #include <mach/host_info.h> 33 #include <mach/host_info.h>
34 #include <mach/i386/thread_status.h>
35 #include <mach/mach_vm.h> 34 #include <mach/mach_vm.h>
36 #include <mach/vm_statistics.h> 35 #include <mach/vm_statistics.h>
37 #include <mach-o/dyld.h> 36 #include <mach-o/dyld.h>
38 #include <mach-o/loader.h> 37 #include <mach-o/loader.h>
39 #include <sys/sysctl.h> 38 #include <sys/sysctl.h>
40 #include <sys/resource.h> 39 #include <sys/resource.h>
41 40
42 #include <CoreFoundation/CoreFoundation.h> 41 #include <CoreFoundation/CoreFoundation.h>
43 42
44 #include "client/mac/handler/minidump_generator.h" 43 #include "client/mac/handler/minidump_generator.h"
45 44
45 #ifdef HAS_ARM_SUPPORT
46 #include <mach/arm/thread_status.h>
47 #endif
46 #ifdef HAS_PPC_SUPPORT 48 #ifdef HAS_PPC_SUPPORT
47 #include <mach/ppc/thread_status.h> 49 #include <mach/ppc/thread_status.h>
48 #endif 50 #endif
51 #ifdef HAS_X86_SUPPORT
52 #include <mach/i386/thread_status.h>
53 #endif
49 54
50 #include "client/minidump_file_writer-inl.h" 55 #include "client/minidump_file_writer-inl.h"
51 #include "common/mac/file_id.h" 56 #include "common/mac/file_id.h"
52 #include "common/mac/string_utilities.h" 57 #include "common/mac/string_utilities.h"
53 58
54 using MacStringUtils::ConvertToString; 59 using MacStringUtils::ConvertToString;
55 using MacStringUtils::IntegerValueAtIndex; 60 using MacStringUtils::IntegerValueAtIndex;
56 61
57 namespace google_breakpad { 62 namespace google_breakpad {
58 63
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
341 346
342 stack_location->start_of_memory_range = start_addr; 347 stack_location->start_of_memory_range = start_addr;
343 stack_location->memory = memory.location(); 348 stack_location->memory = memory.location();
344 349
345 return result; 350 return result;
346 } 351 }
347 352
348 bool MinidumpGenerator::WriteStack(breakpad_thread_state_data_t state, 353 bool MinidumpGenerator::WriteStack(breakpad_thread_state_data_t state,
349 MDMemoryDescriptor *stack_location) { 354 MDMemoryDescriptor *stack_location) {
350 switch (cpu_type_) { 355 switch (cpu_type_) {
356 #ifdef HAS_ARM_SUPPORT
357 case CPU_TYPE_ARM:
358 return WriteStackARM(state, stack_location);
359 #endif
351 #ifdef HAS_PPC_SUPPORT 360 #ifdef HAS_PPC_SUPPORT
352 case CPU_TYPE_POWERPC: 361 case CPU_TYPE_POWERPC:
353 return WriteStackPPC(state, stack_location); 362 return WriteStackPPC(state, stack_location);
354 case CPU_TYPE_POWERPC64: 363 case CPU_TYPE_POWERPC64:
355 return WriteStackPPC64(state, stack_location); 364 return WriteStackPPC64(state, stack_location);
356 #endif 365 #endif
366 #ifdef HAS_X86_SUPPORT
357 case CPU_TYPE_I386: 367 case CPU_TYPE_I386:
358 return WriteStackX86(state, stack_location); 368 return WriteStackX86(state, stack_location);
359 case CPU_TYPE_X86_64: 369 case CPU_TYPE_X86_64:
360 return WriteStackX86_64(state, stack_location); 370 return WriteStackX86_64(state, stack_location);
371 #endif
361 default: 372 default:
362 return false; 373 return false;
363 } 374 }
364 } 375 }
365 376
366 bool MinidumpGenerator::WriteContext(breakpad_thread_state_data_t state, 377 bool MinidumpGenerator::WriteContext(breakpad_thread_state_data_t state,
367 MDLocationDescriptor *register_location) { 378 MDLocationDescriptor *register_location) {
368 switch (cpu_type_) { 379 switch (cpu_type_) {
380 #ifdef HAS_ARM_SUPPORT
381 case CPU_TYPE_ARM:
382 return WriteContextARM(state, register_location);
383 #endif
369 #ifdef HAS_PPC_SUPPORT 384 #ifdef HAS_PPC_SUPPORT
370 case CPU_TYPE_POWERPC: 385 case CPU_TYPE_POWERPC:
371 return WriteContextPPC(state, register_location); 386 return WriteContextPPC(state, register_location);
372 case CPU_TYPE_POWERPC64: 387 case CPU_TYPE_POWERPC64:
373 return WriteContextPPC64(state, register_location); 388 return WriteContextPPC64(state, register_location);
374 #endif 389 #endif
390 #ifdef HAS_X86_SUPPORT
375 case CPU_TYPE_I386: 391 case CPU_TYPE_I386:
376 return WriteContextX86(state, register_location); 392 return WriteContextX86(state, register_location);
377 case CPU_TYPE_X86_64: 393 case CPU_TYPE_X86_64:
378 return WriteContextX86_64(state, register_location); 394 return WriteContextX86_64(state, register_location);
395 #endif
379 default: 396 default:
380 return false; 397 return false;
381 } 398 }
382 } 399 }
383 400
384 u_int64_t MinidumpGenerator::CurrentPCForStack( 401 u_int64_t MinidumpGenerator::CurrentPCForStack(
385 breakpad_thread_state_data_t state) { 402 breakpad_thread_state_data_t state) {
386 switch (cpu_type_) { 403 switch (cpu_type_) {
404 #ifdef HAS_ARM_SUPPORT
405 case CPU_TYPE_ARM:
406 return CurrentPCForStackARM(state);
407 #endif
387 #ifdef HAS_PPC_SUPPORT 408 #ifdef HAS_PPC_SUPPORT
388 case CPU_TYPE_POWERPC: 409 case CPU_TYPE_POWERPC:
389 return CurrentPCForStackPPC(state); 410 return CurrentPCForStackPPC(state);
390 case CPU_TYPE_POWERPC64: 411 case CPU_TYPE_POWERPC64:
391 return CurrentPCForStackPPC64(state); 412 return CurrentPCForStackPPC64(state);
392 #endif 413 #endif
414 #ifdef HAS_X86_SUPPORT
393 case CPU_TYPE_I386: 415 case CPU_TYPE_I386:
394 return CurrentPCForStackX86(state); 416 return CurrentPCForStackX86(state);
395 case CPU_TYPE_X86_64: 417 case CPU_TYPE_X86_64:
396 return CurrentPCForStackX86_64(state); 418 return CurrentPCForStackX86_64(state);
419 #endif
397 default: 420 default:
398 assert("Unknown CPU type!"); 421 assert("Unknown CPU type!");
399 return 0; 422 return 0;
400 } 423 }
401 } 424 }
402 425
426 #ifdef HAS_ARM_SUPPORT
427 bool MinidumpGenerator::WriteStackARM(breakpad_thread_state_data_t state,
428 MDMemoryDescriptor *stack_location) {
429 arm_thread_state_t *machine_state =
430 reinterpret_cast<arm_thread_state_t *>(state);
431 mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, sp);
432 return WriteStackFromStartAddress(start_addr, stack_location);
433 }
434
435 u_int64_t
436 MinidumpGenerator::CurrentPCForStackARM(breakpad_thread_state_data_t state) {
437 arm_thread_state_t *machine_state =
438 reinterpret_cast<arm_thread_state_t *>(state);
439
440 return REGISTER_FROM_THREADSTATE(machine_state, pc);
441 }
442
443 bool MinidumpGenerator::WriteContextARM(breakpad_thread_state_data_t state,
444 MDLocationDescriptor *register_location)
445 {
446 TypedMDRVA<MDRawContextARM> context(&writer_);
447 arm_thread_state_t *machine_state =
448 reinterpret_cast<arm_thread_state_t *>(state);
449
450 if (!context.Allocate())
451 return false;
452
453 *register_location = context.location();
454 MDRawContextARM *context_ptr = context.get();
455 context_ptr->context_flags = MD_CONTEXT_ARM_FULL;
456
457 #define AddReg(a) context_ptr->a = REGISTER_FROM_THREADSTATE(machine_state, a)
Ted Mielczarek 2011/10/06 14:56:09 You only use AddReg once. Doesn't seem worth the #
qsr 2011/10/06 17:48:23 Done.
458 #define AddGPR(a) context_ptr->iregs[a] = REGISTER_FROM_THREADSTATE(machine_stat e, r[a])
459
460 context_ptr->iregs[13] = REGISTER_FROM_THREADSTATE(machine_state, sp);
461 context_ptr->iregs[14] = REGISTER_FROM_THREADSTATE(machine_state, lr);
462 context_ptr->iregs[15] = REGISTER_FROM_THREADSTATE(machine_state, pc);
463 AddReg(cpsr);
464
465 AddGPR(0);
466 AddGPR(1);
467 AddGPR(2);
468 AddGPR(3);
469 AddGPR(4);
470 AddGPR(5);
471 AddGPR(6);
472 AddGPR(7);
473 AddGPR(8);
474 AddGPR(9);
475 AddGPR(10);
476 AddGPR(11);
477 AddGPR(12);
478 #undef AddReg
479 #undef AddGPR
480
481 context_ptr->cpsr = 0;
Ted Mielczarek 2011/10/06 14:56:09 Why are you zeroing this out when you set it above
Mark Mentovai 2011/10/06 14:58:58 You can’t recover this from state->cpsr?
qsr 2011/10/06 17:48:23 Thanks. I let that slipped when I was trying to un
482
Mark Mentovai 2011/10/06 14:58:58 Wow, we never save any floating-point state for an
qsr 2011/10/06 17:48:23 No we don't. I guessed that I won't try new things
483 return true;
484 }
485 #endif
486
403 #ifdef HAS_PCC_SUPPORT 487 #ifdef HAS_PCC_SUPPORT
404 bool MinidumpGenerator::WriteStackPPC(breakpad_thread_state_data_t state, 488 bool MinidumpGenerator::WriteStackPPC(breakpad_thread_state_data_t state,
405 MDMemoryDescriptor *stack_location) { 489 MDMemoryDescriptor *stack_location) {
406 ppc_thread_state_t *machine_state = 490 ppc_thread_state_t *machine_state =
407 reinterpret_cast<ppc_thread_state_t *>(state); 491 reinterpret_cast<ppc_thread_state_t *>(state);
408 mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, r1); 492 mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, r1);
409 return WriteStackFromStartAddress(start_addr, stack_location); 493 return WriteStackFromStartAddress(start_addr, stack_location);
410 } 494 }
411 495
412 bool MinidumpGenerator::WriteStackPPC64(breakpad_thread_state_data_t state, 496 bool MinidumpGenerator::WriteStackPPC64(breakpad_thread_state_data_t state,
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
553 AddGPR(30); 637 AddGPR(30);
554 AddGPR(31); 638 AddGPR(31);
555 #undef AddReg 639 #undef AddReg
556 #undef AddGPR 640 #undef AddGPR
557 641
558 return true; 642 return true;
559 } 643 }
560 644
561 #endif 645 #endif
562 646
647 #ifdef HAS_X86_SUPPORT
563 bool MinidumpGenerator::WriteStackX86(breakpad_thread_state_data_t state, 648 bool MinidumpGenerator::WriteStackX86(breakpad_thread_state_data_t state,
564 MDMemoryDescriptor *stack_location) { 649 MDMemoryDescriptor *stack_location) {
565 i386_thread_state_t *machine_state = 650 i386_thread_state_t *machine_state =
566 reinterpret_cast<i386_thread_state_t *>(state); 651 reinterpret_cast<i386_thread_state_t *>(state);
567 652
568 mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, esp); 653 mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, esp);
569 return WriteStackFromStartAddress(start_addr, stack_location); 654 return WriteStackFromStartAddress(start_addr, stack_location);
570 } 655 }
571 656
572 bool MinidumpGenerator::WriteStackX86_64(breakpad_thread_state_data_t state, 657 bool MinidumpGenerator::WriteStackX86_64(breakpad_thread_state_data_t state,
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 // specifies 32 bits for the flags register, we can truncate safely 756 // specifies 32 bits for the flags register, we can truncate safely
672 // with no loss. 757 // with no loss.
673 context_ptr->eflags = static_cast<u_int32_t>(REGISTER_FROM_THREADSTATE(machine _state, rflags)); 758 context_ptr->eflags = static_cast<u_int32_t>(REGISTER_FROM_THREADSTATE(machine _state, rflags));
674 AddReg(cs); 759 AddReg(cs);
675 AddReg(fs); 760 AddReg(fs);
676 AddReg(gs); 761 AddReg(gs);
677 #undef AddReg 762 #undef AddReg
678 763
679 return true; 764 return true;
680 } 765 }
766 #endif
681 767
682 bool MinidumpGenerator::GetThreadState(thread_act_t target_thread, 768 bool MinidumpGenerator::GetThreadState(thread_act_t target_thread,
683 thread_state_t state, 769 thread_state_t state,
684 mach_msg_type_number_t *count) { 770 mach_msg_type_number_t *count) {
685 thread_state_flavor_t flavor; 771 thread_state_flavor_t flavor;
686 switch (cpu_type_) { 772 switch (cpu_type_) {
773 #ifdef HAS_ARM_SUPPORT
774 case CPU_TYPE_ARM:
775 flavor = ARM_THREAD_STATE;
776 break;
777 #endif
687 #ifdef HAS_PPC_SUPPORT 778 #ifdef HAS_PPC_SUPPORT
688 case CPU_TYPE_POWERPC: 779 case CPU_TYPE_POWERPC:
689 flavor = PPC_THREAD_STATE; 780 flavor = PPC_THREAD_STATE;
690 break; 781 break;
691 case CPU_TYPE_POWERPC64: 782 case CPU_TYPE_POWERPC64:
692 flavor = PPC_THREAD_STATE64; 783 flavor = PPC_THREAD_STATE64;
693 break; 784 break;
694 #endif 785 #endif
786 #ifdef HAS_X86_SUPPORT
695 case CPU_TYPE_I386: 787 case CPU_TYPE_I386:
696 flavor = i386_THREAD_STATE; 788 flavor = i386_THREAD_STATE;
697 break; 789 break;
698 case CPU_TYPE_X86_64: 790 case CPU_TYPE_X86_64:
699 flavor = x86_THREAD_STATE64; 791 flavor = x86_THREAD_STATE64;
700 break; 792 break;
793 #endif
701 default: 794 default:
702 return false; 795 return false;
703 } 796 }
704 return thread_get_state(target_thread, flavor, 797 return thread_get_state(target_thread, flavor,
705 state, count) == KERN_SUCCESS; 798 state, count) == KERN_SUCCESS;
706 } 799 }
707 800
708 bool MinidumpGenerator::WriteThreadStream(mach_port_t thread_id, 801 bool MinidumpGenerator::WriteThreadStream(mach_port_t thread_id,
709 MDRawThread *thread) { 802 MDRawThread *thread) {
710 breakpad_thread_state_data_t state; 803 breakpad_thread_state_data_t state;
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after
920 system_info_stream->stream_type = MD_SYSTEM_INFO_STREAM; 1013 system_info_stream->stream_type = MD_SYSTEM_INFO_STREAM;
921 system_info_stream->location = info.location(); 1014 system_info_stream->location = info.location();
922 1015
923 // CPU Information 1016 // CPU Information
924 uint32_t number_of_processors; 1017 uint32_t number_of_processors;
925 size_t len = sizeof(number_of_processors); 1018 size_t len = sizeof(number_of_processors);
926 sysctlbyname("hw.ncpu", &number_of_processors, &len, NULL, 0); 1019 sysctlbyname("hw.ncpu", &number_of_processors, &len, NULL, 0);
927 MDRawSystemInfo *info_ptr = info.get(); 1020 MDRawSystemInfo *info_ptr = info.get();
928 1021
929 switch (cpu_type_) { 1022 switch (cpu_type_) {
1023 case CPU_TYPE_ARM:
1024 info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_ARM;
1025 break;
930 case CPU_TYPE_POWERPC: 1026 case CPU_TYPE_POWERPC:
931 case CPU_TYPE_POWERPC64: 1027 case CPU_TYPE_POWERPC64:
932 info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_PPC; 1028 info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_PPC;
933 break; 1029 break;
934 case CPU_TYPE_I386: 1030 case CPU_TYPE_I386:
935 case CPU_TYPE_X86_64: 1031 case CPU_TYPE_X86_64:
936 if (cpu_type_ == CPU_TYPE_I386) 1032 if (cpu_type_ == CPU_TYPE_I386)
937 info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_X86; 1033 info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_X86;
938 else 1034 else
939 info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_AMD64; 1035 info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_AMD64;
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
1305 } else { 1401 } else {
1306 info_ptr->validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID; 1402 info_ptr->validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID;
1307 info_ptr->dump_thread_id = handler_thread_; 1403 info_ptr->dump_thread_id = handler_thread_;
1308 info_ptr->requesting_thread_id = 0; 1404 info_ptr->requesting_thread_id = 0;
1309 } 1405 }
1310 1406
1311 return true; 1407 return true;
1312 } 1408 }
1313 1409
1314 } // namespace google_breakpad 1410 } // namespace google_breakpad
OLDNEW

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld 1004:630ec63f810e-tainted