@@ -146,7 +146,7 @@ CrashInfo::EnumerateAndSuspendThreads()
146146// Gather all the necessary crash dump info.
147147//
148148bool
149- CrashInfo::GatherCrashInfo (const char * programPath, MINIDUMP_TYPE minidumpType)
149+ CrashInfo::GatherCrashInfo (MINIDUMP_TYPE minidumpType)
150150{
151151 // Get the process info
152152 if (!GetStatus (m_pid, &m_ppid, &m_tgid, &m_name))
@@ -206,7 +206,7 @@ CrashInfo::GatherCrashInfo(const char* programPath, MINIDUMP_TYPE minidumpType)
206206 }
207207 }
208208 // Gather all the useful memory regions from the DAC
209- if (!EnumerateMemoryRegionsWithDAC (programPath, minidumpType))
209+ if (!EnumerateMemoryRegionsWithDAC (minidumpType))
210210 {
211211 return false ;
212212 }
@@ -363,10 +363,21 @@ CrashInfo::EnumerateModuleMappings()
363363 }
364364 MemoryRegion memoryRegion (regionFlags, start, end, offset, moduleName);
365365
366- if (moduleName != nullptr && *moduleName == ' /' ) {
366+ if (moduleName != nullptr && *moduleName == ' /' )
367+ {
368+ if (m_coreclrPath.empty ())
369+ {
370+ std::string coreclrPath;
371+ coreclrPath.append (moduleName);
372+ size_t last = coreclrPath.rfind (MAKEDLLNAME_A (" coreclr" ));
373+ if (last != -1 ) {
374+ m_coreclrPath = coreclrPath.substr (0 , last);
375+ }
376+ }
367377 m_moduleMappings.insert (memoryRegion);
368378 }
369- else {
379+ else
380+ {
370381 m_otherMappings.insert (memoryRegion);
371382 }
372383 if (linuxGateAddress != nullptr && reinterpret_cast <void *>(start) == linuxGateAddress)
@@ -412,40 +423,15 @@ CrashInfo::GetDSOInfo()
412423 return false ;
413424 }
414425 uint64_t baseAddress = (uint64_t )phdrAddr - sizeof (Ehdr);
415- TRACE (" DSO: base %" PRIA PRIx64 " phdr %p phnum %d\n " , baseAddress, phdrAddr, phnum);
416-
417- // Search for the program PT_DYNAMIC header
418426 ElfW (Dyn)* dynamicAddr = nullptr ;
419- for (int i = 0 ; i < phnum; i++, phdrAddr++)
420- {
421- Phdr ph;
422- if (!ReadMemory (phdrAddr, &ph, sizeof (ph))) {
423- fprintf (stderr, " ReadMemory(%p, %" PRIx " ) phdr FAILED\n " , phdrAddr, sizeof (ph));
424- return false ;
425- }
426- TRACE (" DSO: phdr %p type %d (%x) vaddr %" PRIxA " memsz %" PRIxA " offset %" PRIxA " \n " ,
427- phdrAddr, ph.p_type , ph.p_type , ph.p_vaddr , ph.p_memsz , ph.p_offset );
428427
429- switch (ph.p_type )
430- {
431- case PT_DYNAMIC:
432- dynamicAddr = reinterpret_cast <ElfW (Dyn)*>(ph.p_vaddr );
433- break ;
434-
435- case PT_NOTE:
436- case PT_GNU_EH_FRAME:
437- if (ph.p_vaddr != 0 && ph.p_memsz != 0 ) {
438- InsertMemoryRegion (ph.p_vaddr , ph.p_memsz );
439- }
440- break ;
428+ TRACE (" DSO: base %" PRIA PRIx64 " phdr %p phnum %d\n " , baseAddress, phdrAddr, phnum);
441429
442- case PT_LOAD:
443- MemoryRegion region (0 , ph.p_vaddr , ph.p_vaddr + ph.p_memsz , baseAddress);
444- m_moduleAddresses.insert (region);
445- break ;
446- }
430+ // Enumerate program headers searching for the PT_DYNAMIC header, etc.
431+ if (!EnumerateProgramHeaders (phdrAddr, phnum, baseAddress, &dynamicAddr))
432+ {
433+ return false ;
447434 }
448-
449435 if (dynamicAddr == nullptr ) {
450436 return false ;
451437 }
@@ -542,32 +528,70 @@ CrashInfo::GetELFInfo(uint64_t baseAddress)
542528 {
543529 Phdr* phdrAddr = reinterpret_cast <Phdr*>(baseAddress + ehdr.e_phoff );
544530
545- // Add the program headers and search for the module's note and unwind info segments
546- for (int i = 0 ; i < phnum; i++, phdrAddr++)
531+ if (!EnumerateProgramHeaders (phdrAddr, phnum, baseAddress, nullptr ))
547532 {
548- Phdr ph;
549- if (!ReadMemory (phdrAddr, &ph, sizeof (ph))) {
550- fprintf (stderr, " ReadMemory(%p, %" PRIx " ) phdr FAILED\n " , phdrAddr, sizeof (ph));
551- return false ;
552- }
553- TRACE (" ELF: phdr %p type %d (%x) vaddr %" PRIxA " memsz %" PRIxA " paddr %" PRIxA " filesz %" PRIxA " offset %" PRIxA " align %" PRIxA " \n " ,
554- phdrAddr, ph.p_type , ph.p_type , ph.p_vaddr , ph.p_memsz , ph.p_paddr , ph.p_filesz , ph.p_offset , ph.p_align );
533+ return false ;
534+ }
535+ }
536+
537+ return true ;
538+ }
539+
540+ //
541+ // Enumerate the program headers adding the build id note, unwind frame
542+ // region and module addresses to the crash info.
543+ //
544+ bool
545+ CrashInfo::EnumerateProgramHeaders (Phdr* phdrAddr, int phnum, uint64_t baseAddress, ElfW(Dyn)** pdynamicAddr)
546+ {
547+ uint64_t loadbias = baseAddress;
555548
556- switch (ph.p_type )
549+ for (int i = 0 ; i < phnum; i++)
550+ {
551+ Phdr ph;
552+ if (!ReadMemory (phdrAddr + i, &ph, sizeof (ph))) {
553+ fprintf (stderr, " ReadMemory(%p, %" PRIx " ) phdr FAILED\n " , phdrAddr + i, sizeof (ph));
554+ return false ;
555+ }
556+ if (ph.p_type == PT_LOAD && ph.p_offset == 0 )
557+ {
558+ loadbias -= ph.p_vaddr ;
559+ TRACE (" PHDR: loadbias %" PRIA PRIx64 " \n " , loadbias);
560+ break ;
561+ }
562+ }
563+
564+ for (int i = 0 ; i < phnum; i++)
565+ {
566+ Phdr ph;
567+ if (!ReadMemory (phdrAddr + i, &ph, sizeof (ph))) {
568+ fprintf (stderr, " ReadMemory(%p, %" PRIx " ) phdr FAILED\n " , phdrAddr + i, sizeof (ph));
569+ return false ;
570+ }
571+ TRACE (" PHDR: %p type %d (%x) vaddr %" PRIxA " memsz %" PRIxA " paddr %" PRIxA " filesz %" PRIxA " offset %" PRIxA " align %" PRIxA " \n " ,
572+ phdrAddr + i, ph.p_type , ph.p_type , ph.p_vaddr , ph.p_memsz , ph.p_paddr , ph.p_filesz , ph.p_offset , ph.p_align );
573+
574+ switch (ph.p_type )
575+ {
576+ case PT_DYNAMIC:
577+ if (pdynamicAddr != nullptr )
557578 {
558- case PT_DYNAMIC:
559- case PT_NOTE:
560- case PT_GNU_EH_FRAME:
561- if (ph.p_vaddr != 0 && ph.p_memsz != 0 ) {
562- InsertMemoryRegion (baseAddress + ph.p_vaddr , ph.p_memsz );
563- }
579+ *pdynamicAddr = reinterpret_cast <ElfW (Dyn)*>(loadbias + ph.p_vaddr );
564580 break ;
581+ }
582+ // fall into InsertMemoryRegion
565583
566- case PT_LOAD :
567- MemoryRegion region ( 0 , baseAddress + ph. p_vaddr , baseAddress + ph. p_vaddr + ph. p_memsz , baseAddress);
568- m_moduleAddresses. insert (region);
569- break ;
584+ case PT_NOTE :
585+ case PT_GNU_EH_FRAME:
586+ if (ph. p_vaddr != 0 && ph. p_memsz != 0 ) {
587+ InsertMemoryRegion (loadbias + ph. p_vaddr , ph. p_memsz ) ;
570588 }
589+ break ;
590+
591+ case PT_LOAD:
592+ MemoryRegion region (0 , loadbias + ph.p_vaddr , loadbias + ph.p_vaddr + ph.p_memsz , baseAddress);
593+ m_moduleAddresses.insert (region);
594+ break ;
571595 }
572596 }
573597
@@ -578,7 +602,7 @@ CrashInfo::GetELFInfo(uint64_t baseAddress)
578602// Enumerate all the memory regions using the DAC memory region support given a minidump type
579603//
580604bool
581- CrashInfo::EnumerateMemoryRegionsWithDAC (const char * programPath, MINIDUMP_TYPE minidumpType)
605+ CrashInfo::EnumerateMemoryRegionsWithDAC (MINIDUMP_TYPE minidumpType)
582606{
583607 PFN_CLRDataCreateInstance pfnCLRDataCreateInstance = nullptr ;
584608 ICLRDataEnumMemoryRegions* pClrDataEnumRegions = nullptr ;
@@ -587,50 +611,55 @@ CrashInfo::EnumerateMemoryRegionsWithDAC(const char* programPath, MINIDUMP_TYPE
587611 HRESULT hr = S_OK;
588612 bool result = false ;
589613
590- // We assume that the DAC is in the same location as this createdump exe
591- std::string dacPath;
592- dacPath.append (programPath);
593- dacPath.append (" /" );
594- dacPath.append (MAKEDLLNAME_A (" mscordaccore" ));
595-
596- // Load and initialize the DAC
597- hdac = LoadLibraryA (dacPath.c_str ());
598- if (hdac == nullptr )
599- {
600- fprintf (stderr, " LoadLibraryA(%s) FAILED %d\n " , dacPath.c_str (), GetLastError ());
601- goto exit;
602- }
603- pfnCLRDataCreateInstance = (PFN_CLRDataCreateInstance)GetProcAddress (hdac, " CLRDataCreateInstance" );
604- if (pfnCLRDataCreateInstance == nullptr )
605- {
606- fprintf (stderr, " GetProcAddress(CLRDataCreateInstance) FAILED %d\n " , GetLastError ());
607- goto exit;
608- }
609- if ((minidumpType & MiniDumpWithFullMemory) == 0 )
614+ if (!m_coreclrPath.empty ())
610615 {
611- hr = pfnCLRDataCreateInstance (__uuidof (ICLRDataEnumMemoryRegions), m_dataTarget, (void **)&pClrDataEnumRegions);
612- if (FAILED (hr))
616+ // We assume that the DAC is in the same location as the libcoreclr.so module
617+ std::string dacPath;
618+ dacPath.append (m_coreclrPath);
619+ dacPath.append (MAKEDLLNAME_A (" mscordaccore" ));
620+
621+ // Load and initialize the DAC
622+ hdac = LoadLibraryA (dacPath.c_str ());
623+ if (hdac == nullptr )
624+ {
625+ fprintf (stderr, " LoadLibraryA(%s) FAILED %d\n " , dacPath.c_str (), GetLastError ());
626+ goto exit;
627+ }
628+ pfnCLRDataCreateInstance = (PFN_CLRDataCreateInstance)GetProcAddress (hdac, " CLRDataCreateInstance" );
629+ if (pfnCLRDataCreateInstance == nullptr )
613630 {
614- fprintf (stderr, " CLRDataCreateInstance(ICLRDataEnumMemoryRegions ) FAILED %08x \n " , hr );
631+ fprintf (stderr, " GetProcAddress(CLRDataCreateInstance ) FAILED %d \n " , GetLastError () );
615632 goto exit;
616633 }
617- // Calls CrashInfo::EnumMemoryRegion for each memory region found by the DAC
618- hr = pClrDataEnumRegions->EnumMemoryRegions (this , minidumpType, CLRDATA_ENUM_MEM_DEFAULT);
634+ if ((minidumpType & MiniDumpWithFullMemory) == 0 )
635+ {
636+ hr = pfnCLRDataCreateInstance (__uuidof (ICLRDataEnumMemoryRegions), m_dataTarget, (void **)&pClrDataEnumRegions);
637+ if (FAILED (hr))
638+ {
639+ fprintf (stderr, " CLRDataCreateInstance(ICLRDataEnumMemoryRegions) FAILED %08x\n " , hr);
640+ goto exit;
641+ }
642+ // Calls CrashInfo::EnumMemoryRegion for each memory region found by the DAC
643+ hr = pClrDataEnumRegions->EnumMemoryRegions (this , minidumpType, CLRDATA_ENUM_MEM_DEFAULT);
644+ if (FAILED (hr))
645+ {
646+ fprintf (stderr, " EnumMemoryRegions FAILED %08x\n " , hr);
647+ goto exit;
648+ }
649+ }
650+ hr = pfnCLRDataCreateInstance (__uuidof (IXCLRDataProcess), m_dataTarget, (void **)&pClrDataProcess);
619651 if (FAILED (hr))
620652 {
621- fprintf (stderr, " EnumMemoryRegions FAILED %08x\n " , hr);
653+ fprintf (stderr, " CLRDataCreateInstance(IXCLRDataProcess) FAILED %08x\n " , hr);
654+ goto exit;
655+ }
656+ if (!EnumerateManagedModules (pClrDataProcess))
657+ {
622658 goto exit;
623659 }
624660 }
625- hr = pfnCLRDataCreateInstance (__uuidof (IXCLRDataProcess), m_dataTarget, (void **)&pClrDataProcess);
626- if (FAILED (hr))
627- {
628- fprintf (stderr, " CLRDataCreateInstance(IXCLRDataProcess) FAILED %08x\n " , hr);
629- goto exit;
630- }
631- if (!EnumerateManagedModules (pClrDataProcess))
632- {
633- goto exit;
661+ else {
662+ TRACE (" EnumerateMemoryRegionsWithDAC: coreclr not found; not using DAC\n " );
634663 }
635664 if (!UnwindAllThreads (pClrDataProcess))
636665 {
0 commit comments