# HG changeset patch # Parent 989c2873d1a584bd26eb3cbb4be26d0d4aa8e691 diff --git a/fhandler_process.cc b/fhandler_process.cc --- a/fhandler_process.cc +++ b/fhandler_process.cc @@ -528,6 +528,17 @@ return len + 1; } +/* This function exists for debugging purposes: it can be called from + a debugger or calls to it embedded in cygwin code. + + WARNING: if called early in process startup, be sure to set pass + make_safe=true or set use_safe_process_maps=true before making the + call. This tells format_process_maps to avoid using cygwin features + that may not be initialized yet, at the cost of a less detailed + process map. */ +void print_process_maps (bool make_safe); +static bool use_safe_process_maps = false; + struct dos_drive_mappings { struct mapping { mapping* next; @@ -540,6 +551,9 @@ dos_drive_mappings () : mappings(0) { + if (use_safe_process_maps) + return; // can't use psapi or heap yet... + /* The logical drive strings buffer holds a list of (at most 26) drive names separated by nulls and terminated by a double-null: @@ -613,6 +627,9 @@ heap_info (DWORD pid) : heaps (0) { + if (use_safe_process_maps) + return; // not safe to use the heap + HANDLE hHeapSnap = CreateToolhelp32Snapshot (TH32CS_SNAPHEAPLIST, pid); HEAPLIST32 hl; hl.dwSize = sizeof(hl); @@ -648,6 +665,27 @@ } }; +void +print_process_maps (bool make_safe) +{ + bool saved = use_safe_process_maps; + use_safe_process_maps |= make_safe; + + _pinfo p; + p.dwProcessId = GetCurrentProcessId(); + char* buf = 0; + DWORD done; + _off64_t len = format_process_maps(&p, buf); + WriteFile (GetStdHandle (STD_ERROR_HANDLE), buf, len, &done, 0); + FlushFileBuffers (GetStdHandle (STD_ERROR_HANDLE)); + if (use_safe_process_maps) + VirtualFree (buf, 0, MEM_RELEASE); + else + cfree (buf); + + use_safe_process_maps = saved; +} + static _off64_t format_process_maps (void *data, char *&destbuf) { @@ -688,6 +726,18 @@ cfree (destbuf); destbuf = NULL; } + + if (use_safe_process_maps) + { + maxsize = 256*1024; + destbuf = (char*) VirtualAlloc (NULL, maxsize, MEM_COMMIT, PAGE_READWRITE); + if (!destbuf) + { + system_printf ("Error allocating virtual memory: %E"); + return 0; + } + } + /* Iterate over each VM region in the address space, coalescing memory regions with the same permissions. Once we run out, do one @@ -732,8 +782,16 @@ { size_t newlen = strlen (posix_modname) + 62; if (len + newlen >= maxsize) - destbuf = (char *) crealloc_abort (destbuf, - maxsize += roundup2 (newlen, 2048)); + { + if (use_safe_process_maps) + { + system_printf ("truncating output of format_process_maps to fit available memory"); + return len; + } + else + destbuf = (char *) crealloc_abort (destbuf, + maxsize += roundup2 (newlen, 2048)); + } int written = __small_sprintf (destbuf + len, "%08lx-%08lx %s %08lx %04x:%04x %U ", cur.rbase, cur.rend, cur.a.flags, @@ -753,7 +811,19 @@ { st.st_dev = 0; st.st_ino = 0; - if ((mb.Type & (MEM_MAPPED | MEM_IMAGE) + if (use_safe_process_maps) + { + char const* n; + if (mb.Type & MEM_MAPPED) + n = "[mapped file or shareable region]"; + else if (mb.Type & MEM_IMAGE) + n = "[executable image]"; + else + n = ""; + + strcpy (posix_modname, n); + } + else if ((mb.Type & (MEM_MAPPED | MEM_IMAGE) && GetMappedFileNameW (proc, cur.abase, modname, NT_MAX_PATH))) { PWCHAR dosname = drive_maps.fixup_if_match (modname);