mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-14 21:27:19 +00:00
winedbg: Fallback to PE image when reading memory (minidump).
Signed-off-by: Eric Pouech <epouech@codeweavers.com>
This commit is contained in:
parent
ca95533e8a
commit
aabf6334f3
|
@ -25,6 +25,7 @@
|
||||||
|
|
||||||
#include "debugger.h"
|
#include "debugger.h"
|
||||||
#include "wingdi.h"
|
#include "wingdi.h"
|
||||||
|
#include "winnt.h"
|
||||||
#include "winuser.h"
|
#include "winuser.h"
|
||||||
#include "tlhelp32.h"
|
#include "tlhelp32.h"
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
|
@ -143,6 +144,70 @@ static BOOL tgt_process_minidump_read(HANDLE hProcess, const void* addr,
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* The memory isn't present in minidump. Try to fetch read-only area from PE image. */
|
||||||
|
{
|
||||||
|
IMAGEHLP_MODULEW64 im = {.SizeOfStruct = sizeof(im)};
|
||||||
|
|
||||||
|
if (SymGetModuleInfoW64(dbg_curr_process->handle, (DWORD_PTR)addr, &im))
|
||||||
|
{
|
||||||
|
WCHAR *image_name;
|
||||||
|
HANDLE file, map = 0;
|
||||||
|
void *pe_mapping = NULL;
|
||||||
|
BOOL found = FALSE;
|
||||||
|
const IMAGE_NT_HEADERS *nthdr = NULL;
|
||||||
|
|
||||||
|
image_name = im.LoadedImageName[0] ? im.LoadedImageName : im.ImageName;
|
||||||
|
if ((file = CreateFileW(image_name, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||||
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE &&
|
||||||
|
((map = CreateFileMappingW(file, NULL, PAGE_READONLY, 0, 0, NULL)) != 0) &&
|
||||||
|
((pe_mapping = MapViewOfFile(map, FILE_MAP_READ, 0, 0, 0)) != NULL) &&
|
||||||
|
(nthdr = RtlImageNtHeader(pe_mapping)) != NULL)
|
||||||
|
{
|
||||||
|
DWORD_PTR rva = (DWORD_PTR)addr - im.BaseOfImage;
|
||||||
|
ptrdiff_t size_hdr = (const BYTE*)(IMAGE_FIRST_SECTION(nthdr) + nthdr->FileHeader.NumberOfSections) - (const BYTE*)pe_mapping;
|
||||||
|
|
||||||
|
/* in the PE header ? */
|
||||||
|
if (rva < size_hdr)
|
||||||
|
{
|
||||||
|
if (rva + len > size_hdr)
|
||||||
|
len = size_hdr - rva;
|
||||||
|
memcpy(buffer, (const BYTE*)pe_mapping + rva, len);
|
||||||
|
if (rlen) *rlen = len;
|
||||||
|
found = TRUE;
|
||||||
|
}
|
||||||
|
else /* in read only section ? */
|
||||||
|
{
|
||||||
|
/* Note: RtlImageRvaToSection checks RVA against raw size, so we won't
|
||||||
|
* get section when rva falls into the (raw size, virtual size( interval.
|
||||||
|
*/
|
||||||
|
const IMAGE_SECTION_HEADER *section = RtlImageRvaToSection(nthdr, NULL, rva);
|
||||||
|
if (section && !(section->Characteristics & IMAGE_SCN_MEM_WRITE))
|
||||||
|
{
|
||||||
|
DWORD_PTR offset = rva - section->VirtualAddress;
|
||||||
|
DWORD nw = len;
|
||||||
|
|
||||||
|
if (offset + nw > section->SizeOfRawData)
|
||||||
|
nw = section->SizeOfRawData - offset;
|
||||||
|
memcpy(buffer, (const char*)pe_mapping + section->PointerToRawData + offset, nw);
|
||||||
|
if (nw < len) /* fill with O? */
|
||||||
|
{
|
||||||
|
if (offset + len > section->Misc.VirtualSize)
|
||||||
|
len = section->Misc.VirtualSize - offset;
|
||||||
|
memset((char*)buffer + nw, 0, len - nw);
|
||||||
|
nw = len;
|
||||||
|
}
|
||||||
|
if (rlen) *rlen = nw;
|
||||||
|
found = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pe_mapping) UnmapViewOfFile(pe_mapping);
|
||||||
|
if (map) CloseHandle(map);
|
||||||
|
if (file != INVALID_HANDLE_VALUE) CloseHandle(file);
|
||||||
|
if (found) return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* FIXME: this is a dirty hack to let the last frame in a bt to work
|
/* FIXME: this is a dirty hack to let the last frame in a bt to work
|
||||||
* However, we need to check who's to blame, this code or the current
|
* However, we need to check who's to blame, this code or the current
|
||||||
* dbghelp!StackWalk implementation
|
* dbghelp!StackWalk implementation
|
||||||
|
|
Loading…
Reference in a new issue