minidump_generator.cc revision 8f2b058398bb5b0f658320a62ffd82a7ebc82a16
1// Copyright (c) 2006, Google Inc. 2// All rights reserved. 3// 4// Redistribution and use in source and binary forms, with or without 5// modification, are permitted provided that the following conditions are 6// met: 7// 8// * Redistributions of source code must retain the above copyright 9// notice, this list of conditions and the following disclaimer. 10// * Redistributions in binary form must reproduce the above 11// copyright notice, this list of conditions and the following disclaimer 12// in the documentation and/or other materials provided with the 13// distribution. 14// * Neither the name of Google Inc. nor the names of its 15// contributors may be used to endorse or promote products derived from 16// this software without specific prior written permission. 17// 18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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. 29 30#include <algorithm> 31#include <cstdio> 32 33#include <mach/host_info.h> 34#include <mach/i386/thread_status.h> 35#include <mach/mach_vm.h> 36#include <mach/vm_statistics.h> 37#include <mach-o/dyld.h> 38#include <mach-o/loader.h> 39#include <sys/sysctl.h> 40#include <sys/resource.h> 41 42#include <CoreFoundation/CoreFoundation.h> 43 44#include "client/mac/handler/minidump_generator.h" 45 46#ifdef HAS_PPC_SUPPORT 47#include <mach/ppc/thread_status.h> 48#endif 49 50#include "client/minidump_file_writer-inl.h" 51#include "common/mac/file_id.h" 52#include "common/mac/string_utilities.h" 53 54using MacStringUtils::ConvertToString; 55using MacStringUtils::IntegerValueAtIndex; 56 57namespace google_breakpad { 58 59#if __LP64__ 60#define LC_SEGMENT_ARCH LC_SEGMENT_64 61#else 62#define LC_SEGMENT_ARCH LC_SEGMENT 63#endif 64 65// constructor when generating from within the crashed process 66MinidumpGenerator::MinidumpGenerator() 67 : writer_(), 68 exception_type_(0), 69 exception_code_(0), 70 exception_subcode_(0), 71 exception_thread_(0), 72 crashing_task_(mach_task_self()), 73 handler_thread_(mach_thread_self()), 74 cpu_type_(DynamicImages::GetNativeCPUType()), 75 dynamic_images_(NULL), 76 memory_blocks_(&allocator_) { 77 GatherSystemInformation(); 78} 79 80// constructor when generating from a different process than the 81// crashed process 82MinidumpGenerator::MinidumpGenerator(mach_port_t crashing_task, 83 mach_port_t handler_thread) 84 : writer_(), 85 exception_type_(0), 86 exception_code_(0), 87 exception_subcode_(0), 88 exception_thread_(0), 89 crashing_task_(crashing_task), 90 handler_thread_(handler_thread), 91 cpu_type_(DynamicImages::GetNativeCPUType()), 92 dynamic_images_(NULL), 93 memory_blocks_(&allocator_) { 94 if (crashing_task != mach_task_self()) { 95 dynamic_images_ = new DynamicImages(crashing_task_); 96 cpu_type_ = dynamic_images_->GetCPUType(); 97 } else { 98 dynamic_images_ = NULL; 99 cpu_type_ = DynamicImages::GetNativeCPUType(); 100 } 101 102 GatherSystemInformation(); 103} 104 105MinidumpGenerator::~MinidumpGenerator() { 106 delete dynamic_images_; 107} 108 109char MinidumpGenerator::build_string_[16]; 110int MinidumpGenerator::os_major_version_ = 0; 111int MinidumpGenerator::os_minor_version_ = 0; 112int MinidumpGenerator::os_build_number_ = 0; 113 114// static 115void MinidumpGenerator::GatherSystemInformation() { 116 // If this is non-zero, then we've already gathered the information 117 if (os_major_version_) 118 return; 119 120 // This code extracts the version and build information from the OS 121 CFStringRef vers_path = 122 CFSTR("/System/Library/CoreServices/SystemVersion.plist"); 123 CFURLRef sys_vers = 124 CFURLCreateWithFileSystemPath(NULL, 125 vers_path, 126 kCFURLPOSIXPathStyle, 127 false); 128 CFDataRef data; 129 SInt32 error; 130 CFURLCreateDataAndPropertiesFromResource(NULL, sys_vers, &data, NULL, NULL, 131 &error); 132 133 if (!data) 134 return; 135 136 CFDictionaryRef list = static_cast<CFDictionaryRef> 137 (CFPropertyListCreateFromXMLData(NULL, data, kCFPropertyListImmutable, 138 NULL)); 139 if (!list) 140 return; 141 142 CFStringRef build_version = static_cast<CFStringRef> 143 (CFDictionaryGetValue(list, CFSTR("ProductBuildVersion"))); 144 CFStringRef product_version = static_cast<CFStringRef> 145 (CFDictionaryGetValue(list, CFSTR("ProductVersion"))); 146 string build_str = ConvertToString(build_version); 147 string product_str = ConvertToString(product_version); 148 149 CFRelease(list); 150 CFRelease(sys_vers); 151 CFRelease(data); 152 153 strlcpy(build_string_, build_str.c_str(), sizeof(build_string_)); 154 155 // Parse the string that looks like "10.4.8" 156 os_major_version_ = IntegerValueAtIndex(product_str, 0); 157 os_minor_version_ = IntegerValueAtIndex(product_str, 1); 158 os_build_number_ = IntegerValueAtIndex(product_str, 2); 159} 160 161string MinidumpGenerator::UniqueNameInDirectory(const string &dir, 162 string *unique_name) { 163 CFUUIDRef uuid = CFUUIDCreate(NULL); 164 CFStringRef uuid_cfstr = CFUUIDCreateString(NULL, uuid); 165 CFRelease(uuid); 166 string file_name(ConvertToString(uuid_cfstr)); 167 CFRelease(uuid_cfstr); 168 string path(dir); 169 170 // Ensure that the directory (if non-empty) has a trailing slash so that 171 // we can append the file name and have a valid pathname. 172 if (!dir.empty()) { 173 if (dir.at(dir.size() - 1) != '/') 174 path.append(1, '/'); 175 } 176 177 path.append(file_name); 178 path.append(".dmp"); 179 180 if (unique_name) 181 *unique_name = file_name; 182 183 return path; 184} 185 186bool MinidumpGenerator::Write(const char *path) { 187 WriteStreamFN writers[] = { 188 &MinidumpGenerator::WriteThreadListStream, 189 &MinidumpGenerator::WriteMemoryListStream, 190 &MinidumpGenerator::WriteSystemInfoStream, 191 &MinidumpGenerator::WriteModuleListStream, 192 &MinidumpGenerator::WriteMiscInfoStream, 193 &MinidumpGenerator::WriteBreakpadInfoStream, 194 // Exception stream needs to be the last entry in this array as it may 195 // be omitted in the case where the minidump is written without an 196 // exception. 197 &MinidumpGenerator::WriteExceptionStream, 198 }; 199 bool result = false; 200 201 // If opening was successful, create the header, directory, and call each 202 // writer. The destructor for the TypedMDRVAs will cause the data to be 203 // flushed. The destructor for the MinidumpFileWriter will close the file. 204 if (writer_.Open(path)) { 205 TypedMDRVA<MDRawHeader> header(&writer_); 206 TypedMDRVA<MDRawDirectory> dir(&writer_); 207 208 if (!header.Allocate()) 209 return false; 210 211 int writer_count = static_cast<int>(sizeof(writers) / sizeof(writers[0])); 212 213 // If we don't have exception information, don't write out the 214 // exception stream 215 if (!exception_thread_ && !exception_type_) 216 --writer_count; 217 218 // Add space for all writers 219 if (!dir.AllocateArray(writer_count)) 220 return false; 221 222 MDRawHeader *header_ptr = header.get(); 223 header_ptr->signature = MD_HEADER_SIGNATURE; 224 header_ptr->version = MD_HEADER_VERSION; 225 time(reinterpret_cast<time_t *>(&(header_ptr->time_date_stamp))); 226 header_ptr->stream_count = writer_count; 227 header_ptr->stream_directory_rva = dir.position(); 228 229 MDRawDirectory local_dir; 230 result = true; 231 for (int i = 0; (result) && (i < writer_count); ++i) { 232 result = (this->*writers[i])(&local_dir); 233 234 if (result) 235 dir.CopyIndex(i, &local_dir); 236 } 237 } 238 return result; 239} 240 241size_t MinidumpGenerator::CalculateStackSize(mach_vm_address_t start_addr) { 242 mach_vm_address_t stack_region_base = start_addr; 243 mach_vm_size_t stack_region_size; 244 natural_t nesting_level = 0; 245 vm_region_submap_info_64 submap_info; 246 mach_msg_type_number_t info_count = VM_REGION_SUBMAP_INFO_COUNT_64; 247 248 vm_region_recurse_info_t region_info; 249 region_info = reinterpret_cast<vm_region_recurse_info_t>(&submap_info); 250 251 if (start_addr == 0) { 252 return 0; 253 } 254 255 kern_return_t result = 256 mach_vm_region_recurse(crashing_task_, &stack_region_base, 257 &stack_region_size, &nesting_level, 258 region_info, 259 &info_count); 260 261 if (start_addr < stack_region_base) { 262 // probably stack corruption, since mach_vm_region had to go 263 // higher in the process address space to find a valid region. 264 return 0; 265 } 266 267 if (((cpu_type_ & CPU_ARCH_ABI64) && 268 (stack_region_base + stack_region_size) == TOP_OF_THREAD0_STACK_64BIT) || 269 (!(cpu_type_ & CPU_ARCH_ABI64) && 270 (stack_region_base + stack_region_size) == TOP_OF_THREAD0_STACK_32BIT)) { 271 // The stack for thread 0 needs to extend all the way to 272 // 0xc0000000 on 32 bit and 00007fff5fc00000 on 64bit. HOWEVER, 273 // for many processes, the stack is first created in one page 274 // below this, and is then later extended to a much larger size by 275 // creating a new VM region immediately below the initial page. 276 277 // You can see this for yourself by running vmmap on a "hello, 278 // world" program 279 280 // Because of the above, we'll add 4k to include the original 281 // stack frame page. 282 // This method of finding the stack region needs to be done in 283 // a better way; the breakpad issue 247 is tracking this. 284 stack_region_size += 0x1000; 285 } 286 287 return result == KERN_SUCCESS ? 288 stack_region_base + stack_region_size - start_addr : 0; 289} 290 291bool MinidumpGenerator::WriteStackFromStartAddress( 292 mach_vm_address_t start_addr, 293 MDMemoryDescriptor *stack_location) { 294 UntypedMDRVA memory(&writer_); 295 296 bool result = false; 297 size_t size = CalculateStackSize(start_addr); 298 299 if (size == 0) { 300 // In some situations the stack address for the thread can come back 0. 301 // In these cases we skip over the threads in question and stuff the 302 // stack with a clearly borked value. 303 start_addr = 0xDEADBEEF; 304 size = 16; 305 if (!memory.Allocate(size)) 306 return false; 307 308 unsigned long long dummy_stack[2]; // Fill dummy stack with 16 bytes of 309 // junk. 310 dummy_stack[0] = 0xDEADBEEF; 311 dummy_stack[1] = 0xDEADBEEF; 312 313 result = memory.Copy(dummy_stack, size); 314 } else { 315 316 if (!memory.Allocate(size)) 317 return false; 318 319 if (dynamic_images_) { 320 vector<uint8_t> stack_memory; 321 if (ReadTaskMemory(crashing_task_, 322 start_addr, 323 size, 324 stack_memory) != KERN_SUCCESS) { 325 return false; 326 } 327 328 result = memory.Copy(&stack_memory[0], size); 329 } else { 330 result = memory.Copy(reinterpret_cast<const void *>(start_addr), size); 331 } 332 } 333 334 stack_location->start_of_memory_range = start_addr; 335 stack_location->memory = memory.location(); 336 337 return result; 338} 339 340bool MinidumpGenerator::WriteStack(breakpad_thread_state_data_t state, 341 MDMemoryDescriptor *stack_location) { 342 switch (cpu_type_) { 343#ifdef HAS_PPC_SUPPORT 344 case CPU_TYPE_POWERPC: 345 return WriteStackPPC(state, stack_location); 346 case CPU_TYPE_POWERPC64: 347 return WriteStackPPC64(state, stack_location); 348#endif 349 case CPU_TYPE_I386: 350 return WriteStackX86(state, stack_location); 351 case CPU_TYPE_X86_64: 352 return WriteStackX86_64(state, stack_location); 353 default: 354 return false; 355 } 356} 357 358bool MinidumpGenerator::WriteContext(breakpad_thread_state_data_t state, 359 MDLocationDescriptor *register_location) { 360 switch (cpu_type_) { 361#ifdef HAS_PPC_SUPPORT 362 case CPU_TYPE_POWERPC: 363 return WriteContextPPC(state, register_location); 364 case CPU_TYPE_POWERPC64: 365 return WriteContextPPC64(state, register_location); 366#endif 367 case CPU_TYPE_I386: 368 return WriteContextX86(state, register_location); 369 case CPU_TYPE_X86_64: 370 return WriteContextX86_64(state, register_location); 371 default: 372 return false; 373 } 374} 375 376u_int64_t MinidumpGenerator::CurrentPCForStack( 377 breakpad_thread_state_data_t state) { 378 switch (cpu_type_) { 379#ifdef HAS_PPC_SUPPORT 380 case CPU_TYPE_POWERPC: 381 return CurrentPCForStackPPC(state); 382 case CPU_TYPE_POWERPC64: 383 return CurrentPCForStackPPC64(state); 384#endif 385 case CPU_TYPE_I386: 386 return CurrentPCForStackX86(state); 387 case CPU_TYPE_X86_64: 388 return CurrentPCForStackX86_64(state); 389 default: 390 assert("Unknown CPU type!"); 391 return 0; 392 } 393} 394 395#ifdef HAS_PCC_SUPPORT 396bool MinidumpGenerator::WriteStackPPC(breakpad_thread_state_data_t state, 397 MDMemoryDescriptor *stack_location) { 398 ppc_thread_state_t *machine_state = 399 reinterpret_cast<ppc_thread_state_t *>(state); 400 mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, r1); 401 return WriteStackFromStartAddress(start_addr, stack_location); 402} 403 404bool MinidumpGenerator::WriteStackPPC64(breakpad_thread_state_data_t state, 405 MDMemoryDescriptor *stack_location) { 406 ppc_thread_state64_t *machine_state = 407 reinterpret_cast<ppc_thread_state64_t *>(state); 408 mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, r1); 409 return WriteStackFromStartAddress(start_addr, stack_location); 410} 411 412u_int64_t 413MinidumpGenerator::CurrentPCForStackPPC(breakpad_thread_state_data_t state) { 414 ppc_thread_state_t *machine_state = 415 reinterpret_cast<ppc_thread_state_t *>(state); 416 417 return REGISTER_FROM_THREADSTATE(machine_state, srr0); 418} 419 420u_int64_t 421MinidumpGenerator::CurrentPCForStackPPC64(breakpad_thread_state_data_t state) { 422 ppc_thread_state64_t *machine_state = 423 reinterpret_cast<ppc_thread_state64_t *>(state); 424 425 return REGISTER_FROM_THREADSTATE(machine_state, srr0); 426} 427 428bool MinidumpGenerator::WriteContextPPC(breakpad_thread_state_data_t state, 429 MDLocationDescriptor *register_location) 430{ 431 TypedMDRVA<MDRawContextPPC> context(&writer_); 432 ppc_thread_state_t *machine_state = 433 reinterpret_cast<ppc_thread_state_t *>(state); 434 435 if (!context.Allocate()) 436 return false; 437 438 *register_location = context.location(); 439 MDRawContextPPC *context_ptr = context.get(); 440 context_ptr->context_flags = MD_CONTEXT_PPC_BASE; 441 442#define AddReg(a) context_ptr->a = REGISTER_FROM_THREADSTATE(machine_state, a) 443#define AddGPR(a) context_ptr->gpr[a] = REGISTER_FROM_THREADSTATE(machine_state, r ## a) 444 445 AddReg(srr0); 446 AddReg(cr); 447 AddReg(xer); 448 AddReg(ctr); 449 AddReg(lr); 450 AddReg(vrsave); 451 452 AddGPR(0); 453 AddGPR(1); 454 AddGPR(2); 455 AddGPR(3); 456 AddGPR(4); 457 AddGPR(5); 458 AddGPR(6); 459 AddGPR(7); 460 AddGPR(8); 461 AddGPR(9); 462 AddGPR(10); 463 AddGPR(11); 464 AddGPR(12); 465 AddGPR(13); 466 AddGPR(14); 467 AddGPR(15); 468 AddGPR(16); 469 AddGPR(17); 470 AddGPR(18); 471 AddGPR(19); 472 AddGPR(20); 473 AddGPR(21); 474 AddGPR(22); 475 AddGPR(23); 476 AddGPR(24); 477 AddGPR(25); 478 AddGPR(26); 479 AddGPR(27); 480 AddGPR(28); 481 AddGPR(29); 482 AddGPR(30); 483 AddGPR(31); 484 AddReg(mq); 485#undef AddReg 486#undef AddGPR 487 488 return true; 489} 490 491bool MinidumpGenerator::WriteContextPPC64( 492 breakpad_thread_state_data_t state, 493 MDLocationDescriptor *register_location) { 494 TypedMDRVA<MDRawContextPPC64> context(&writer_); 495 ppc_thread_state64_t *machine_state = 496 reinterpret_cast<ppc_thread_state64_t *>(state); 497 498 if (!context.Allocate()) 499 return false; 500 501 *register_location = context.location(); 502 MDRawContextPPC64 *context_ptr = context.get(); 503 context_ptr->context_flags = MD_CONTEXT_PPC_BASE; 504 505#define AddReg(a) context_ptr->a = REGISTER_FROM_THREADSTATE(machine_state, a) 506#define AddGPR(a) context_ptr->gpr[a] = REGISTER_FROM_THREADSTATE(machine_state, r ## a) 507 508 AddReg(srr0); 509 AddReg(cr); 510 AddReg(xer); 511 AddReg(ctr); 512 AddReg(lr); 513 AddReg(vrsave); 514 515 AddGPR(0); 516 AddGPR(1); 517 AddGPR(2); 518 AddGPR(3); 519 AddGPR(4); 520 AddGPR(5); 521 AddGPR(6); 522 AddGPR(7); 523 AddGPR(8); 524 AddGPR(9); 525 AddGPR(10); 526 AddGPR(11); 527 AddGPR(12); 528 AddGPR(13); 529 AddGPR(14); 530 AddGPR(15); 531 AddGPR(16); 532 AddGPR(17); 533 AddGPR(18); 534 AddGPR(19); 535 AddGPR(20); 536 AddGPR(21); 537 AddGPR(22); 538 AddGPR(23); 539 AddGPR(24); 540 AddGPR(25); 541 AddGPR(26); 542 AddGPR(27); 543 AddGPR(28); 544 AddGPR(29); 545 AddGPR(30); 546 AddGPR(31); 547#undef AddReg 548#undef AddGPR 549 550 return true; 551} 552 553#endif 554 555bool MinidumpGenerator::WriteStackX86(breakpad_thread_state_data_t state, 556 MDMemoryDescriptor *stack_location) { 557 i386_thread_state_t *machine_state = 558 reinterpret_cast<i386_thread_state_t *>(state); 559 560 mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, esp); 561 return WriteStackFromStartAddress(start_addr, stack_location); 562} 563 564bool MinidumpGenerator::WriteStackX86_64(breakpad_thread_state_data_t state, 565 MDMemoryDescriptor *stack_location) { 566 x86_thread_state64_t *machine_state = 567 reinterpret_cast<x86_thread_state64_t *>(state); 568 569 mach_vm_address_t start_addr = REGISTER_FROM_THREADSTATE(machine_state, rsp); 570 return WriteStackFromStartAddress(start_addr, stack_location); 571} 572 573u_int64_t 574MinidumpGenerator::CurrentPCForStackX86(breakpad_thread_state_data_t state) { 575 i386_thread_state_t *machine_state = 576 reinterpret_cast<i386_thread_state_t *>(state); 577 578 return REGISTER_FROM_THREADSTATE(machine_state, eip); 579} 580 581u_int64_t 582MinidumpGenerator::CurrentPCForStackX86_64(breakpad_thread_state_data_t state) { 583 x86_thread_state64_t *machine_state = 584 reinterpret_cast<x86_thread_state64_t *>(state); 585 586 return REGISTER_FROM_THREADSTATE(machine_state, rip); 587} 588 589bool MinidumpGenerator::WriteContextX86(breakpad_thread_state_data_t state, 590 MDLocationDescriptor *register_location) 591{ 592 TypedMDRVA<MDRawContextX86> context(&writer_); 593 i386_thread_state_t *machine_state = 594 reinterpret_cast<i386_thread_state_t *>(state); 595 596 if (!context.Allocate()) 597 return false; 598 599 *register_location = context.location(); 600 MDRawContextX86 *context_ptr = context.get(); 601 602#define AddReg(a) context_ptr->a = REGISTER_FROM_THREADSTATE(machine_state, a) 603 604 context_ptr->context_flags = MD_CONTEXT_X86; 605 AddReg(eax); 606 AddReg(ebx); 607 AddReg(ecx); 608 AddReg(edx); 609 AddReg(esi); 610 AddReg(edi); 611 AddReg(ebp); 612 AddReg(esp); 613 614 AddReg(cs); 615 AddReg(ds); 616 AddReg(ss); 617 AddReg(es); 618 AddReg(fs); 619 AddReg(gs); 620 AddReg(eflags); 621 622 AddReg(eip); 623#undef AddReg 624 625 return true; 626} 627 628bool MinidumpGenerator::WriteContextX86_64( 629 breakpad_thread_state_data_t state, 630 MDLocationDescriptor *register_location) { 631 TypedMDRVA<MDRawContextAMD64> context(&writer_); 632 x86_thread_state64_t *machine_state = 633 reinterpret_cast<x86_thread_state64_t *>(state); 634 635 if (!context.Allocate()) 636 return false; 637 638 *register_location = context.location(); 639 MDRawContextAMD64 *context_ptr = context.get(); 640 641#define AddReg(a) context_ptr->a = REGISTER_FROM_THREADSTATE(machine_state, a) 642 643 context_ptr->context_flags = MD_CONTEXT_AMD64; 644 AddReg(rax); 645 AddReg(rbx); 646 AddReg(rcx); 647 AddReg(rdx); 648 AddReg(rdi); 649 AddReg(rsi); 650 AddReg(rbp); 651 AddReg(rsp); 652 AddReg(r8); 653 AddReg(r9); 654 AddReg(r10); 655 AddReg(r11); 656 AddReg(r12); 657 AddReg(r13); 658 AddReg(r14); 659 AddReg(r15); 660 AddReg(rip); 661 // according to AMD's software developer guide, bits above 18 are 662 // not used in the flags register. Since the minidump format 663 // specifies 32 bits for the flags register, we can truncate safely 664 // with no loss. 665 context_ptr->eflags = static_cast<u_int32_t>(REGISTER_FROM_THREADSTATE(machine_state, rflags)); 666 AddReg(cs); 667 AddReg(fs); 668 AddReg(gs); 669#undef AddReg 670 671 return true; 672} 673 674bool MinidumpGenerator::GetThreadState(thread_act_t target_thread, 675 thread_state_t state, 676 mach_msg_type_number_t *count) { 677 thread_state_flavor_t flavor; 678 switch (cpu_type_) { 679#ifdef HAS_PPC_SUPPORT 680 case CPU_TYPE_POWERPC: 681 flavor = PPC_THREAD_STATE; 682 break; 683 case CPU_TYPE_POWERPC64: 684 flavor = PPC_THREAD_STATE64; 685 break; 686#endif 687 case CPU_TYPE_I386: 688 flavor = i386_THREAD_STATE; 689 break; 690 case CPU_TYPE_X86_64: 691 flavor = x86_THREAD_STATE64; 692 break; 693 default: 694 return false; 695 } 696 return thread_get_state(target_thread, flavor, 697 state, count) == KERN_SUCCESS; 698} 699 700bool MinidumpGenerator::WriteThreadStream(mach_port_t thread_id, 701 MDRawThread *thread) { 702 breakpad_thread_state_data_t state; 703 mach_msg_type_number_t state_count 704 = static_cast<mach_msg_type_number_t>(sizeof(state)); 705 706 if (GetThreadState(thread_id, state, &state_count)) { 707 if (!WriteStack(state, &thread->stack)) 708 return false; 709 710 memory_blocks_.push_back(thread->stack); 711 712 if (!WriteContext(state, &thread->thread_context)) 713 return false; 714 715 thread->thread_id = thread_id; 716 } else { 717 return false; 718 } 719 720 return true; 721} 722 723bool MinidumpGenerator::WriteThreadListStream( 724 MDRawDirectory *thread_list_stream) { 725 TypedMDRVA<MDRawThreadList> list(&writer_); 726 thread_act_port_array_t threads_for_task; 727 mach_msg_type_number_t thread_count; 728 int non_generator_thread_count; 729 730 if (task_threads(crashing_task_, &threads_for_task, &thread_count)) 731 return false; 732 733 // Don't include the generator thread 734 if (handler_thread_ != MACH_PORT_NULL) 735 non_generator_thread_count = thread_count - 1; 736 else 737 non_generator_thread_count = thread_count; 738 if (!list.AllocateObjectAndArray(non_generator_thread_count, 739 sizeof(MDRawThread))) 740 return false; 741 742 thread_list_stream->stream_type = MD_THREAD_LIST_STREAM; 743 thread_list_stream->location = list.location(); 744 745 list.get()->number_of_threads = non_generator_thread_count; 746 747 MDRawThread thread; 748 int thread_idx = 0; 749 750 for (unsigned int i = 0; i < thread_count; ++i) { 751 memset(&thread, 0, sizeof(MDRawThread)); 752 753 if (threads_for_task[i] != handler_thread_) { 754 if (!WriteThreadStream(threads_for_task[i], &thread)) 755 return false; 756 757 list.CopyIndexAfterObject(thread_idx++, &thread, sizeof(MDRawThread)); 758 } 759 } 760 761 return true; 762} 763 764bool MinidumpGenerator::WriteMemoryListStream( 765 MDRawDirectory *memory_list_stream) { 766 TypedMDRVA<MDRawMemoryList> list(&writer_); 767 768 // If the dump has an exception, include some memory around the 769 // instruction pointer. 770 const size_t kIPMemorySize = 256; // bytes 771 bool have_ip_memory = false; 772 MDMemoryDescriptor ip_memory_d; 773 if (exception_thread_ && exception_type_) { 774 breakpad_thread_state_data_t state; 775 mach_msg_type_number_t stateCount 776 = static_cast<mach_msg_type_number_t>(sizeof(state)); 777 778 if (thread_get_state(exception_thread_, 779 BREAKPAD_MACHINE_THREAD_STATE, 780 state, 781 &stateCount) == KERN_SUCCESS) { 782 u_int64_t ip = CurrentPCForStack(state); 783 // Bound it to the upper and lower bounds of the region 784 // it's contained within. If it's not in a known memory region, 785 // don't bother trying to write it. 786 mach_vm_address_t addr = ip; 787 mach_vm_size_t size; 788 natural_t nesting_level = 0; 789 vm_region_submap_info_64 info; 790 mach_msg_type_number_t info_count = VM_REGION_SUBMAP_INFO_COUNT_64; 791 792 kern_return_t ret = 793 mach_vm_region_recurse(crashing_task_, 794 &addr, 795 &size, 796 &nesting_level, 797 (vm_region_recurse_info_t)&info, 798 &info_count); 799 if (ret == KERN_SUCCESS && ip >= addr && ip < (addr + size)) { 800 // Try to get 128 bytes before and after the IP, but 801 // settle for whatever's available. 802 ip_memory_d.start_of_memory_range = 803 std::max(uintptr_t(addr), 804 uintptr_t(ip - (kIPMemorySize / 2))); 805 uintptr_t end_of_range = 806 std::min(uintptr_t(ip + (kIPMemorySize / 2)), 807 uintptr_t(addr + size)); 808 ip_memory_d.memory.data_size = 809 end_of_range - ip_memory_d.start_of_memory_range; 810 have_ip_memory = true; 811 // This needs to get appended to the list even though 812 // the memory bytes aren't filled in yet so the entire 813 // list can be written first. The memory bytes will get filled 814 // in after the memory list is written. 815 memory_blocks_.push_back(ip_memory_d); 816 } 817 } 818 } 819 820 // Now fill in the memory list and write it. 821 unsigned memory_count = memory_blocks_.size(); 822 if (!list.AllocateObjectAndArray(memory_count, 823 sizeof(MDMemoryDescriptor))) 824 return false; 825 826 memory_list_stream->stream_type = MD_MEMORY_LIST_STREAM; 827 memory_list_stream->location = list.location(); 828 829 list.get()->number_of_memory_ranges = memory_count; 830 831 unsigned int i; 832 for (i = 0; i < memory_count; ++i) { 833 list.CopyIndexAfterObject(i, &memory_blocks_[i], 834 sizeof(MDMemoryDescriptor)); 835 } 836 837 if (have_ip_memory) { 838 // Now read the memory around the instruction pointer. 839 UntypedMDRVA ip_memory(&writer_); 840 if (!ip_memory.Allocate(ip_memory_d.memory.data_size)) 841 return false; 842 843 if (dynamic_images_) { 844 // Out-of-process. 845 vector<uint8_t> memory; 846 if (ReadTaskMemory(crashing_task_, 847 ip_memory_d.start_of_memory_range, 848 ip_memory_d.memory.data_size, 849 memory) != KERN_SUCCESS) { 850 return false; 851 } 852 853 ip_memory.Copy(&memory[0], ip_memory_d.memory.data_size); 854 } else { 855 // In-process, just copy from local memory. 856 ip_memory.Copy( 857 reinterpret_cast<const void *>(ip_memory_d.start_of_memory_range), 858 ip_memory_d.memory.data_size); 859 } 860 861 ip_memory_d.memory = ip_memory.location(); 862 // Write this again now that the data location is filled in. 863 list.CopyIndexAfterObject(i - 1, &ip_memory_d, 864 sizeof(MDMemoryDescriptor)); 865 } 866 867 return true; 868} 869 870bool 871MinidumpGenerator::WriteExceptionStream(MDRawDirectory *exception_stream) { 872 TypedMDRVA<MDRawExceptionStream> exception(&writer_); 873 874 if (!exception.Allocate()) 875 return false; 876 877 exception_stream->stream_type = MD_EXCEPTION_STREAM; 878 exception_stream->location = exception.location(); 879 MDRawExceptionStream *exception_ptr = exception.get(); 880 exception_ptr->thread_id = exception_thread_; 881 882 // This naming is confusing, but it is the proper translation from 883 // mach naming to minidump naming. 884 exception_ptr->exception_record.exception_code = exception_type_; 885 exception_ptr->exception_record.exception_flags = exception_code_; 886 887 breakpad_thread_state_data_t state; 888 mach_msg_type_number_t state_count 889 = static_cast<mach_msg_type_number_t>(sizeof(state)); 890 891 if (!GetThreadState(exception_thread_, state, &state_count)) 892 return false; 893 894 if (!WriteContext(state, &exception_ptr->thread_context)) 895 return false; 896 897 if (exception_type_ == EXC_BAD_ACCESS) 898 exception_ptr->exception_record.exception_address = exception_subcode_; 899 else 900 exception_ptr->exception_record.exception_address = CurrentPCForStack(state); 901 902 return true; 903} 904 905bool MinidumpGenerator::WriteSystemInfoStream( 906 MDRawDirectory *system_info_stream) { 907 TypedMDRVA<MDRawSystemInfo> info(&writer_); 908 909 if (!info.Allocate()) 910 return false; 911 912 system_info_stream->stream_type = MD_SYSTEM_INFO_STREAM; 913 system_info_stream->location = info.location(); 914 915 // CPU Information 916 uint32_t number_of_processors; 917 size_t len = sizeof(number_of_processors); 918 sysctlbyname("hw.ncpu", &number_of_processors, &len, NULL, 0); 919 MDRawSystemInfo *info_ptr = info.get(); 920 921 switch (cpu_type_) { 922 case CPU_TYPE_POWERPC: 923 case CPU_TYPE_POWERPC64: 924 info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_PPC; 925 break; 926 case CPU_TYPE_I386: 927 case CPU_TYPE_X86_64: 928 if (cpu_type_ == CPU_TYPE_I386) 929 info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_X86; 930 else 931 info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_AMD64; 932#ifdef __i386__ 933 // ebx is used for PIC code, so we need 934 // to preserve it. 935#define cpuid(op,eax,ebx,ecx,edx) \ 936 asm ("pushl %%ebx \n\t" \ 937 "cpuid \n\t" \ 938 "movl %%ebx,%1 \n\t" \ 939 "popl %%ebx" \ 940 : "=a" (eax), \ 941 "=g" (ebx), \ 942 "=c" (ecx), \ 943 "=d" (edx) \ 944 : "0" (op)) 945#elif defined(__x86_64__) 946 947#define cpuid(op,eax,ebx,ecx,edx) \ 948 asm ("cpuid \n\t" \ 949 : "=a" (eax), \ 950 "=b" (ebx), \ 951 "=c" (ecx), \ 952 "=d" (edx) \ 953 : "0" (op)) 954#endif 955 956#if defined(__i386__) || defined(__x86_64__) 957 int unused, unused2; 958 // get vendor id 959 cpuid(0, unused, info_ptr->cpu.x86_cpu_info.vendor_id[0], 960 info_ptr->cpu.x86_cpu_info.vendor_id[2], 961 info_ptr->cpu.x86_cpu_info.vendor_id[1]); 962 // get version and feature info 963 cpuid(1, info_ptr->cpu.x86_cpu_info.version_information, unused, unused2, 964 info_ptr->cpu.x86_cpu_info.feature_information); 965 966 // family 967 info_ptr->processor_level = 968 (info_ptr->cpu.x86_cpu_info.version_information & 0xF00) >> 8; 969 // 0xMMSS (Model, Stepping) 970 info_ptr->processor_revision = 971 (info_ptr->cpu.x86_cpu_info.version_information & 0xF) | 972 ((info_ptr->cpu.x86_cpu_info.version_information & 0xF0) << 4); 973 974 // decode extended model info 975 if (info_ptr->processor_level == 0xF || 976 info_ptr->processor_level == 0x6) { 977 info_ptr->processor_revision |= 978 ((info_ptr->cpu.x86_cpu_info.version_information & 0xF0000) >> 4); 979 } 980 981 // decode extended family info 982 if (info_ptr->processor_level == 0xF) { 983 info_ptr->processor_level += 984 ((info_ptr->cpu.x86_cpu_info.version_information & 0xFF00000) >> 20); 985 } 986 987#endif // __i386__ || __x86_64_ 988 break; 989 default: 990 info_ptr->processor_architecture = MD_CPU_ARCHITECTURE_UNKNOWN; 991 break; 992 } 993 994 info_ptr->number_of_processors = number_of_processors; 995 info_ptr->platform_id = MD_OS_MAC_OS_X; 996 997 MDLocationDescriptor build_string_loc; 998 999 if (!writer_.WriteString(build_string_, 0, 1000 &build_string_loc)) 1001 return false; 1002 1003 info_ptr->csd_version_rva = build_string_loc.rva; 1004 info_ptr->major_version = os_major_version_; 1005 info_ptr->minor_version = os_minor_version_; 1006 info_ptr->build_number = os_build_number_; 1007 1008 return true; 1009} 1010 1011bool MinidumpGenerator::WriteModuleStream(unsigned int index, 1012 MDRawModule *module) { 1013 if (dynamic_images_) { 1014 // we're in a different process than the crashed process 1015 DynamicImage *image = dynamic_images_->GetImage(index); 1016 1017 if (!image) 1018 return false; 1019 1020 memset(module, 0, sizeof(MDRawModule)); 1021 1022 MDLocationDescriptor string_location; 1023 1024 string name = image->GetFilePath(); 1025 if (!writer_.WriteString(name.c_str(), 0, &string_location)) 1026 return false; 1027 1028 module->base_of_image = image->GetVMAddr() + image->GetVMAddrSlide(); 1029 module->size_of_image = static_cast<u_int32_t>(image->GetVMSize()); 1030 module->module_name_rva = string_location.rva; 1031 1032 // We'll skip the executable module, because they don't have 1033 // LC_ID_DYLIB load commands, and the crash processing server gets 1034 // version information from the Plist file, anyway. 1035 if (index != (uint32_t)FindExecutableModule()) { 1036 module->version_info.signature = MD_VSFIXEDFILEINFO_SIGNATURE; 1037 module->version_info.struct_version |= MD_VSFIXEDFILEINFO_VERSION; 1038 // Convert MAC dylib version format, which is a 32 bit number, to the 1039 // format used by minidump. The mac format is <16 bits>.<8 bits>.<8 bits> 1040 // so it fits nicely into the windows version with some massaging 1041 // The mapping is: 1042 // 1) upper 16 bits of MAC version go to lower 16 bits of product HI 1043 // 2) Next most significant 8 bits go to upper 16 bits of product LO 1044 // 3) Least significant 8 bits go to lower 16 bits of product LO 1045 uint32_t modVersion = image->GetVersion(); 1046 module->version_info.file_version_hi = 0; 1047 module->version_info.file_version_hi = modVersion >> 16; 1048 module->version_info.file_version_lo |= (modVersion & 0xff00) << 8; 1049 module->version_info.file_version_lo |= (modVersion & 0xff); 1050 } 1051 1052 if (!WriteCVRecord(module, image->GetCPUType(), name.c_str())) { 1053 return false; 1054 } 1055 } else { 1056 // Getting module info in the crashed process 1057 const breakpad_mach_header *header; 1058 header = (breakpad_mach_header*)_dyld_get_image_header(index); 1059 if (!header) 1060 return false; 1061 1062#ifdef __LP64__ 1063 assert(header->magic == MH_MAGIC_64); 1064 1065 if(header->magic != MH_MAGIC_64) 1066 return false; 1067#else 1068 assert(header->magic == MH_MAGIC); 1069 1070 if(header->magic != MH_MAGIC) 1071 return false; 1072#endif 1073 1074 int cpu_type = header->cputype; 1075 unsigned long slide = _dyld_get_image_vmaddr_slide(index); 1076 const char* name = _dyld_get_image_name(index); 1077 const struct load_command *cmd = 1078 reinterpret_cast<const struct load_command *>(header + 1); 1079 1080 memset(module, 0, sizeof(MDRawModule)); 1081 1082 for (unsigned int i = 0; cmd && (i < header->ncmds); i++) { 1083 if (cmd->cmd == LC_SEGMENT_ARCH) { 1084 1085 const breakpad_mach_segment_command *seg = 1086 reinterpret_cast<const breakpad_mach_segment_command *>(cmd); 1087 1088 if (!strcmp(seg->segname, "__TEXT")) { 1089 MDLocationDescriptor string_location; 1090 1091 if (!writer_.WriteString(name, 0, &string_location)) 1092 return false; 1093 1094 module->base_of_image = seg->vmaddr + slide; 1095 module->size_of_image = static_cast<u_int32_t>(seg->vmsize); 1096 module->module_name_rva = string_location.rva; 1097 1098 if (!WriteCVRecord(module, cpu_type, name)) 1099 return false; 1100 1101 return true; 1102 } 1103 } 1104 1105 cmd = reinterpret_cast<struct load_command*>((char *)cmd + cmd->cmdsize); 1106 } 1107 } 1108 1109 return true; 1110} 1111 1112int MinidumpGenerator::FindExecutableModule() { 1113 if (dynamic_images_) { 1114 int index = dynamic_images_->GetExecutableImageIndex(); 1115 1116 if (index >= 0) { 1117 return index; 1118 } 1119 } else { 1120 int image_count = _dyld_image_count(); 1121 const struct mach_header *header; 1122 1123 for (int index = 0; index < image_count; ++index) { 1124 header = _dyld_get_image_header(index); 1125 1126 if (header->filetype == MH_EXECUTE) 1127 return index; 1128 } 1129 } 1130 1131 // failed - just use the first image 1132 return 0; 1133} 1134 1135bool MinidumpGenerator::WriteCVRecord(MDRawModule *module, int cpu_type, 1136 const char *module_path) { 1137 TypedMDRVA<MDCVInfoPDB70> cv(&writer_); 1138 1139 // Only return the last path component of the full module path 1140 const char *module_name = strrchr(module_path, '/'); 1141 1142 // Increment past the slash 1143 if (module_name) 1144 ++module_name; 1145 else 1146 module_name = "<Unknown>"; 1147 1148 size_t module_name_length = strlen(module_name); 1149 1150 if (!cv.AllocateObjectAndArray(module_name_length + 1, sizeof(u_int8_t))) 1151 return false; 1152 1153 if (!cv.CopyIndexAfterObject(0, module_name, module_name_length)) 1154 return false; 1155 1156 module->cv_record = cv.location(); 1157 MDCVInfoPDB70 *cv_ptr = cv.get(); 1158 cv_ptr->cv_signature = MD_CVINFOPDB70_SIGNATURE; 1159 cv_ptr->age = 0; 1160 1161 // Get the module identifier 1162 FileID file_id(module_path); 1163 unsigned char identifier[16]; 1164 1165 if (file_id.MachoIdentifier(cpu_type, identifier)) { 1166 cv_ptr->signature.data1 = (uint32_t)identifier[0] << 24 | 1167 (uint32_t)identifier[1] << 16 | (uint32_t)identifier[2] << 8 | 1168 (uint32_t)identifier[3]; 1169 cv_ptr->signature.data2 = (uint32_t)identifier[4] << 8 | identifier[5]; 1170 cv_ptr->signature.data3 = (uint32_t)identifier[6] << 8 | identifier[7]; 1171 cv_ptr->signature.data4[0] = identifier[8]; 1172 cv_ptr->signature.data4[1] = identifier[9]; 1173 cv_ptr->signature.data4[2] = identifier[10]; 1174 cv_ptr->signature.data4[3] = identifier[11]; 1175 cv_ptr->signature.data4[4] = identifier[12]; 1176 cv_ptr->signature.data4[5] = identifier[13]; 1177 cv_ptr->signature.data4[6] = identifier[14]; 1178 cv_ptr->signature.data4[7] = identifier[15]; 1179 } 1180 1181 return true; 1182} 1183 1184bool MinidumpGenerator::WriteModuleListStream( 1185 MDRawDirectory *module_list_stream) { 1186 TypedMDRVA<MDRawModuleList> list(&writer_); 1187 1188 int image_count = dynamic_images_ ? 1189 dynamic_images_->GetImageCount() : _dyld_image_count(); 1190 1191 if (!list.AllocateObjectAndArray(image_count, MD_MODULE_SIZE)) 1192 return false; 1193 1194 module_list_stream->stream_type = MD_MODULE_LIST_STREAM; 1195 module_list_stream->location = list.location(); 1196 list.get()->number_of_modules = image_count; 1197 1198 // Write out the executable module as the first one 1199 MDRawModule module; 1200 int executableIndex = FindExecutableModule(); 1201 1202 if (!WriteModuleStream(executableIndex, &module)) { 1203 return false; 1204 } 1205 1206 list.CopyIndexAfterObject(0, &module, MD_MODULE_SIZE); 1207 int destinationIndex = 1; // Write all other modules after this one 1208 1209 for (int i = 0; i < image_count; ++i) { 1210 if (i != executableIndex) { 1211 if (!WriteModuleStream(i, &module)) { 1212 return false; 1213 } 1214 1215 list.CopyIndexAfterObject(destinationIndex++, &module, MD_MODULE_SIZE); 1216 } 1217 } 1218 1219 return true; 1220} 1221 1222bool MinidumpGenerator::WriteMiscInfoStream(MDRawDirectory *misc_info_stream) { 1223 TypedMDRVA<MDRawMiscInfo> info(&writer_); 1224 1225 if (!info.Allocate()) 1226 return false; 1227 1228 misc_info_stream->stream_type = MD_MISC_INFO_STREAM; 1229 misc_info_stream->location = info.location(); 1230 1231 MDRawMiscInfo *info_ptr = info.get(); 1232 info_ptr->size_of_info = static_cast<u_int32_t>(sizeof(MDRawMiscInfo)); 1233 info_ptr->flags1 = MD_MISCINFO_FLAGS1_PROCESS_ID | 1234 MD_MISCINFO_FLAGS1_PROCESS_TIMES | 1235 MD_MISCINFO_FLAGS1_PROCESSOR_POWER_INFO; 1236 1237 // Process ID 1238 info_ptr->process_id = getpid(); 1239 1240 // Times 1241 struct rusage usage; 1242 if (getrusage(RUSAGE_SELF, &usage) != -1) { 1243 // Omit the fractional time since the MDRawMiscInfo only wants seconds 1244 info_ptr->process_user_time = 1245 static_cast<u_int32_t>(usage.ru_utime.tv_sec); 1246 info_ptr->process_kernel_time = 1247 static_cast<u_int32_t>(usage.ru_stime.tv_sec); 1248 } 1249 int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PID, info_ptr->process_id }; 1250 u_int mibsize = static_cast<u_int>(sizeof(mib) / sizeof(mib[0])); 1251 size_t size; 1252 if (!sysctl(mib, mibsize, NULL, &size, NULL, 0)) { 1253 mach_vm_address_t addr; 1254 if (mach_vm_allocate(mach_task_self(), 1255 &addr, 1256 size, 1257 true) == KERN_SUCCESS) { 1258 struct kinfo_proc *proc = (struct kinfo_proc *)addr; 1259 if (!sysctl(mib, mibsize, proc, &size, NULL, 0)) 1260 info_ptr->process_create_time = 1261 static_cast<u_int32_t>(proc->kp_proc.p_starttime.tv_sec); 1262 mach_vm_deallocate(mach_task_self(), addr, size); 1263 } 1264 } 1265 1266 // Speed 1267 uint64_t speed; 1268 const uint64_t kOneMillion = 1000 * 1000; 1269 size = sizeof(speed); 1270 sysctlbyname("hw.cpufrequency_max", &speed, &size, NULL, 0); 1271 info_ptr->processor_max_mhz = static_cast<u_int32_t>(speed / kOneMillion); 1272 info_ptr->processor_mhz_limit = static_cast<u_int32_t>(speed / kOneMillion); 1273 size = sizeof(speed); 1274 sysctlbyname("hw.cpufrequency", &speed, &size, NULL, 0); 1275 info_ptr->processor_current_mhz = static_cast<u_int32_t>(speed / kOneMillion); 1276 1277 return true; 1278} 1279 1280bool MinidumpGenerator::WriteBreakpadInfoStream( 1281 MDRawDirectory *breakpad_info_stream) { 1282 TypedMDRVA<MDRawBreakpadInfo> info(&writer_); 1283 1284 if (!info.Allocate()) 1285 return false; 1286 1287 breakpad_info_stream->stream_type = MD_BREAKPAD_INFO_STREAM; 1288 breakpad_info_stream->location = info.location(); 1289 MDRawBreakpadInfo *info_ptr = info.get(); 1290 1291 if (exception_thread_ && exception_type_) { 1292 info_ptr->validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID | 1293 MD_BREAKPAD_INFO_VALID_REQUESTING_THREAD_ID; 1294 info_ptr->dump_thread_id = handler_thread_; 1295 info_ptr->requesting_thread_id = exception_thread_; 1296 } else { 1297 info_ptr->validity = MD_BREAKPAD_INFO_VALID_DUMP_THREAD_ID; 1298 info_ptr->dump_thread_id = handler_thread_; 1299 info_ptr->requesting_thread_id = 0; 1300 } 1301 1302 return true; 1303} 1304 1305} // namespace google_breakpad 1306