[ASan/Win] Add basic support for MemoryRangeIsAvailable and DumpProcessMap to make it easier to debug startup shadow mapping failures

llvm-svn: 224856
This commit is contained in:
Timur Iskhodzhanov 2014-12-26 14:28:32 +00:00
parent 103084691d
commit a04b33b9de
2 changed files with 47 additions and 5 deletions

View File

@ -20,6 +20,7 @@
#include <windows.h>
#include <dbghelp.h>
#include <io.h>
#include <psapi.h>
#include <stdlib.h>
#include "sanitizer_common.h"
@ -132,8 +133,10 @@ void FlushUnneededShadowMemory(uptr addr, uptr size) {
}
bool MemoryRangeIsAvailable(uptr range_start, uptr range_end) {
// FIXME: shall we do anything here on Windows?
return true;
MEMORY_BASIC_INFORMATION mbi;
CHECK(VirtualQuery((void *)range_start, &mbi, sizeof(mbi)));
return mbi.Protect & PAGE_NOACCESS &&
(uptr)mbi.BaseAddress + mbi.RegionSize >= range_end;
}
void *MapFileToMemory(const char *file_name, uptr *buff_size) {
@ -188,7 +191,43 @@ u32 GetUid() {
}
void DumpProcessMap() {
UNIMPLEMENTED();
Report("Dumping process modules:\n");
HANDLE cur_process = GetCurrentProcess();
// Query the list of modules. Start by assuming there are no more than 256
// modules and retry if that's not sufficient.
HMODULE *modules = 0;
uptr modules_buffer_size = sizeof(HMODULE) * 256;
DWORD bytes_required;
while (!modules) {
modules = (HMODULE *)MmapOrDie(modules_buffer_size, __FUNCTION__);
CHECK(EnumProcessModules(cur_process, modules, modules_buffer_size,
&bytes_required));
if (bytes_required > modules_buffer_size) {
// Either there turned out to be more than 256 modules, or new modules
// could have loaded since the last try. Retry.
UnmapOrDie(modules, modules_buffer_size);
modules = 0;
modules_buffer_size = bytes_required;
}
}
for (size_t i = 0; i < bytes_required / sizeof(HMODULE); ++i) {
char module_name[MAX_PATH];
bool got_module_name = GetModuleFileNameEx(
cur_process, modules[i], module_name, sizeof(module_name));
MODULEINFO mi;
if (GetModuleInformation(cur_process, modules[i], &mi, sizeof(mi))) {
Printf("\t%p-%p %s\n", mi.lpBaseOfDll,
(void *)((uptr)mi.lpBaseOfDll + mi.SizeOfImage),
got_module_name ? module_name : "[no name]");
} else if (got_module_name) {
Printf("\t???-??? %s\n", module_name);
} else {
Printf("\t???\n");
}
}
UnmapOrDie(modules, modules_buffer_size);
}
void DisableCoreDumperIfNecessary() {

View File

@ -9,6 +9,9 @@ int main() {
printf("Hello, world!\n");
scanf("%s", bigchunk);
// CHECK-NOT: Hello, world!
// CHECK: ERROR: AddressSanitizer failed to allocate
// CHECK: ReserveShadowMemoryRange failed
// CHECK: Shadow memory range interleaves with an existing memory mapping.
// CHECK: Dumping process modules:
// CHECK-DAG: 0x{{[0-9a-f]*}}-0x{{[0-9a-f]*}} {{.*}}shadow_mapping_failure
// CHECK-DAG: 0x{{[0-9a-f]*}}-0x{{[0-9a-f]*}} {{.*}}kernel32.dll
// CHECK-DAG: 0x{{[0-9a-f]*}}-0x{{[0-9a-f]*}} {{.*}}ntdll.dll
}