public inbox for cygwin-patches@cygwin.com
 help / color / mirror / Atom feed
* [PATCH] Improve strace to log most Windows debug events
@ 2015-06-10 12:05 Jon TURNEY
  2015-06-10 14:11 ` Corinna Vinschen
  2015-06-10 18:44 ` Jon TURNEY
  0 siblings, 2 replies; 7+ messages in thread
From: Jon TURNEY @ 2015-06-10 12:05 UTC (permalink / raw)
  To: cygwin-patches; +Cc: Jon TURNEY

Not sure if this is wanted, but on a couple of occasions recently I have been
presented with strace output which contains an exception at an address in an
unknown module (i.e. not in the cygwin DLL or the main executable), so here is a
patch which adds some more information, including DLL load addresses, to help
interpret such straces.

2015-06-07  Jon Turney  <jon.turney@dronecode.org.uk>

	* strace.cc (proc_child): Log process and thread create and exit,
	and DLL load and unload.
	(GetFileNameFromHandle): New function.
	* Makefile.in (strace.exe): Link against psapi.dll.

Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
---
 winsup/utils/ChangeLog   |  7 ++++++
 winsup/utils/Makefile.in |  2 +-
 winsup/utils/strace.cc   | 58 ++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 66 insertions(+), 1 deletion(-)

diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog
index bfdb42a..7561a58 100644
--- a/winsup/utils/ChangeLog
+++ b/winsup/utils/ChangeLog
@@ -1,3 +1,10 @@
+2015-06-07  Jon Turney  <jon.turney@dronecode.org.uk>
+
+	* strace.cc (proc_child): Log process and thread create and exit,
+	and DLL load and unload.
+	(GetFileNameFromHandle): New function.
+	* Makefile.in (strace.exe): Link against psapi.dll.
+
 2015-04-21  Corinna Vinschen  <corinna@vinschen.de>
 
 	* tzmap-from-unicode.org: Convert Calcutta to Kolkata.
diff --git a/winsup/utils/Makefile.in b/winsup/utils/Makefile.in
index fe81d87..4dfe349 100644
--- a/winsup/utils/Makefile.in
+++ b/winsup/utils/Makefile.in
@@ -101,7 +101,7 @@ cygcheck.exe: ${CYGCHECK_OBJS}
 cygpath.o: CXXFLAGS += -fno-threadsafe-statics
 cygpath.exe: CYGWIN_LDFLAGS += -lcygwin -luserenv -lntdll
 ps.exe: CYGWIN_LDFLAGS += -lcygwin -lpsapi -lntdll
-strace.exe: MINGW_LDFLAGS += -lntdll
+strace.exe: MINGW_LDFLAGS += -lntdll -lpsapi
 
 ldd.exe:CYGWIN_LDFLAGS += -lpsapi
 pldd.exe: CYGWIN_LDFLAGS += -lpsapi
diff --git a/winsup/utils/strace.cc b/winsup/utils/strace.cc
index 73096ab..f54cab5 100644
--- a/winsup/utils/strace.cc
+++ b/winsup/utils/strace.cc
@@ -12,6 +12,7 @@ Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
 details. */
 
 #include <windows.h>
+#include <psapi.h>
 #include <winternl.h>
 #define cygwin_internal cygwin_internal_dontuse
 #include <stdio.h>
@@ -637,6 +638,36 @@ handle_output_debug_string (DWORD id, LPVOID p, unsigned mask, FILE *ofile)
     fflush (ofile);
 }
 
+// This is a pretty tragic way to convert HANDLE -> filename, but this is the
+// the way MSDN suggest to do it if you want to be portable to Windows versions
+// prior to 6.0, where GetFinalPathNameByHandle() isn't available.
+static BOOL
+GetFileNameFromHandle(HANDLE hFile, WCHAR pszFilename[MAX_PATH+1])
+{
+  HANDLE hFileMap;
+  BOOL result = FALSE;
+
+  // Create a file mapping object.
+  hFileMap = CreateFileMapping (hFile, NULL, PAGE_READONLY, 0, 1, NULL);
+  if (hFileMap)
+    {
+      // Create a file mapping to get the file name.
+      void* pMem = MapViewOfFile (hFileMap, FILE_MAP_READ, 0, 0, 1);
+      if (pMem)
+	{
+	  if (GetMappedFileNameW (GetCurrentProcess (), pMem, pszFilename,
+				  MAX_PATH))
+	    {
+	      result = TRUE;
+	    }
+	  UnmapViewOfFile(pMem);
+	}
+    CloseHandle(hFileMap);
+  }
+
+  return result;
+}
+
 static DWORD
 proc_child (unsigned mask, FILE *ofile, pid_t pid)
 {
@@ -670,19 +701,38 @@ proc_child (unsigned mask, FILE *ofile, pid_t pid)
       switch (ev.dwDebugEventCode)
 	{
 	case CREATE_PROCESS_DEBUG_EVENT:
+	  fprintf (ofile, "--- Process %lu created\n", ev.dwProcessId);
 	  if (ev.u.CreateProcessInfo.hFile)
 	    CloseHandle (ev.u.CreateProcessInfo.hFile);
 	  add_child (ev.dwProcessId, ev.u.CreateProcessInfo.hProcess);
 	  break;
 
 	case CREATE_THREAD_DEBUG_EVENT:
+	  fprintf (ofile, "--- Process %lu thread %lu created\n",
+		   ev.dwProcessId, ev.dwThreadId);
 	  break;
 
 	case LOAD_DLL_DEBUG_EVENT:
+	  {
+	    // lpImageName is not always populated, so find the filename for
+	    // hFile instead
+	    WCHAR dllname[MAX_PATH+1];
+	    if (!GetFileNameFromHandle(ev.u.LoadDll.hFile, dllname))
+		wcscpy(dllname, L"(unknown)");
+
+	    fprintf (ofile, "--- Process %lu loaded %ls at %p\n",
+		     ev.dwProcessId, dllname, ev.u.LoadDll.lpBaseOfDll);
+	  }
+
 	  if (ev.u.LoadDll.hFile)
 	    CloseHandle (ev.u.LoadDll.hFile);
 	  break;
 
+	case UNLOAD_DLL_DEBUG_EVENT:
+	  fprintf (ofile, "--- Process %lu unloaded DLL at %p\n",
+		   ev.dwProcessId, ev.u.UnloadDll.lpBaseOfDll);
+	  break;
+
 	case OUTPUT_DEBUG_STRING_EVENT:
 	  handle_output_debug_string (ev.dwProcessId,
 				      ev.u.DebugString.lpDebugStringData,
@@ -690,9 +740,17 @@ proc_child (unsigned mask, FILE *ofile, pid_t pid)
 	  break;
 
 	case EXIT_PROCESS_DEBUG_EVENT:
+	  fprintf (ofile, "--- Process %lu exited with status 0x%lx\n",
+		   ev.dwProcessId, ev.u.ExitProcess.dwExitCode);
 	  res = ev.u.ExitProcess.dwExitCode;
 	  remove_child (ev.dwProcessId);
 	  break;
+
+	case EXIT_THREAD_DEBUG_EVENT:
+	  fprintf (ofile, "--- Process %lu thread %lu exited with status 0x%lx\n",
+		   ev.dwProcessId, ev.dwThreadId, ev.u.ExitThread.dwExitCode);
+	  break;
+
 	case EXCEPTION_DEBUG_EVENT:
 	  if (ev.u.Exception.ExceptionRecord.ExceptionCode
 	      != (DWORD) STATUS_BREAKPOINT)
-- 
2.1.4

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2015-06-10 18:47 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-06-10 12:05 [PATCH] Improve strace to log most Windows debug events Jon TURNEY
2015-06-10 14:11 ` Corinna Vinschen
2015-06-10 14:18   ` Corinna Vinschen
2015-06-10 15:44     ` Corinna Vinschen
2015-06-10 17:23       ` Corinna Vinschen
2015-06-10 18:47         ` Jon TURNEY
2015-06-10 18:44 ` Jon TURNEY

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).