compress generated minidumps
authorVictor Kirhenshtein <victor@netxms.org>
Mon, 30 Oct 2017 14:19:43 +0000 (16:19 +0200)
committerVictor Kirhenshtein <victor@netxms.org>
Mon, 30 Oct 2017 14:36:11 +0000 (16:36 +0200)
include/nms_util.h
src/libnetxms/Makefile.am
src/libnetxms/Makefile.w32
src/libnetxms/libnetxms.vcproj
src/libnetxms/seh.cpp
src/libnetxms/ztools.cpp [new file with mode: 0644]
src/server/netxmsd/netxmsd.cpp

index 798ec12..6896ff1 100644 (file)
@@ -2642,6 +2642,9 @@ void LIBNETXMS_EXPORTABLE StartMainLoop(ThreadFunction pfSignalHandler, ThreadFu
 
 String LIBNETXMS_EXPORTABLE GenerateLineDiff(const String& left, const String& right);
 
 
 String LIBNETXMS_EXPORTABLE GenerateLineDiff(const String& left, const String& right);
 
+bool LIBNETXMS_EXPORTABLE DeflateFile(const TCHAR *inputFile, const TCHAR *outputFile = NULL);
+int LIBNETXMS_EXPORTABLE DeflateFileStream(FILE *source, FILE *dest, bool gzipFormat);
+
 #endif
 
 #endif   /* _nms_util_h_ */
 #endif
 
 #endif   /* _nms_util_h_ */
index a19af4c..50b1156 100644 (file)
@@ -11,7 +11,7 @@ SOURCES = array.cpp base64.cpp bytestream.cpp cc_mb.cpp cc_ucs2.cpp \
          strmapbase.cpp strptime.c \
          strset.cpp strtoll.c strtoull.c table.cpp threads.cpp timegm.c \
          tools.cpp tp.cpp unicode.cpp uuid.cpp wcstoll.c wcstoull.c xml.cpp \
          strmapbase.cpp strptime.c \
          strset.cpp strtoll.c strtoull.c table.cpp threads.cpp timegm.c \
          tools.cpp tp.cpp unicode.cpp uuid.cpp wcstoll.c wcstoull.c xml.cpp \
-         wcscasecmp.cpp wcslcat.c wcslcpy.c wcsncasecmp.cpp
+         wcscasecmp.cpp wcslcat.c wcslcpy.c wcsncasecmp.cpp ztools.cpp
 
 lib_LTLIBRARIES = libnetxms.la
 
 
 lib_LTLIBRARIES = libnetxms.la
 
index 8689daf..74e2f25 100644 (file)
@@ -14,7 +14,7 @@ SOURCES = array.cpp base64.cpp bytestream.cpp cc_mb.cpp cc_ucs2.cpp \
        strmap.cpp strmapbase.cpp strptime.c strset.cpp \
        strtoll.c strtoull.c table.cpp threads.cpp timegm.c tools.cpp \
        tp.cpp unicode.cpp uuid.cpp wcslcat.c wcslcpy.c wcstoll.c \
        strmap.cpp strmapbase.cpp strptime.c strset.cpp \
        strtoll.c strtoull.c table.cpp threads.cpp timegm.c tools.cpp \
        tp.cpp unicode.cpp uuid.cpp wcslcat.c wcslcpy.c wcstoll.c \
-       wcstoull.c xml.cpp
+       wcstoull.c xml.cpp ztools.cpp
 
 CPPFLAGS = /I "$(NETXMS_BASE)\src\libexpat\libexpat" /I "$(NETXMS_BASE)\src\zlib" /DLIBNETXMS_EXPORTS
 LIBS = libexpat.lib libtre.lib jansson.lib nxzlib.lib ws2_32.lib dbghelp.lib psapi.lib rpcrt4.lib iphlpapi.lib crypt32.lib
 
 CPPFLAGS = /I "$(NETXMS_BASE)\src\libexpat\libexpat" /I "$(NETXMS_BASE)\src\zlib" /DLIBNETXMS_EXPORTS
 LIBS = libexpat.lib libtre.lib jansson.lib nxzlib.lib ws2_32.lib dbghelp.lib psapi.lib rpcrt4.lib iphlpapi.lib crypt32.lib
index b3c577d..4a84d3c 100644 (file)
                                RelativePath=".\xml.cpp"
                                >
                        </File>
                                RelativePath=".\xml.cpp"
                                >
                        </File>
+                       <File
+                               RelativePath=".\ztools.cpp"
+                               >
+                       </File>
                </Filter>
                <Filter
                        Name="Header Files"
                </Filter>
                <Filter
                        Name="Header Files"
index d9d81fa..44f751a 100644 (file)
@@ -354,10 +354,19 @@ BOOL LIBNETXMS_EXPORTABLE SEHServiceExceptionHandler(EXCEPTION_POINTERS *pInfo)
       usi.UserStreamCount = 1;
       usi.UserStreamArray = &us;
 
       usi.UserStreamCount = 1;
       usi.UserStreamArray = &us;
 
-      MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile,
-            static_cast<MINIDUMP_TYPE>((m_writeFullDump ? MiniDumpWithFullMemory : MiniDumpNormal) | MiniDumpWithHandleData | MiniDumpWithProcessThreadData),
-            &mei, &usi, NULL);
-      CloseHandle(hFile);
+      if (MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), hFile,
+                static_cast<MINIDUMP_TYPE>((m_writeFullDump ? MiniDumpWithFullMemory : MiniDumpNormal) | MiniDumpWithHandleData | MiniDumpWithProcessThreadData),
+                &mei, &usi, NULL))
+      {
+         CloseHandle(hFile);
+         if (DeflateFile(szDumpFile))
+            DeleteFile(szDumpFile);
+      }
+      else
+      {
+         CloseHandle(hFile);
+         DeleteFile(szDumpFile);
+      }
    }
 
        // Write event log
    }
 
        // Write event log
diff --git a/src/libnetxms/ztools.cpp b/src/libnetxms/ztools.cpp
new file mode 100644 (file)
index 0000000..4f5cba1
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+** NetXMS - Network Management System
+** Copyright (C) 2003-2017 Victor Kirhenshtein
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU Lesser General Public License as published
+** by the Free Software Foundation; either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU Lesser General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+**
+** File: ztools.cpp
+**
+**/
+
+#include "libnetxms.h"
+#include <zlib.h>
+
+/**
+ * Deflate given file stream
+ */
+int LIBNETXMS_EXPORTABLE DeflateFileStream(FILE *source, FILE *dest, bool gzipFormat)
+{
+   /* allocate deflate state */
+   z_stream strm;
+   strm.zalloc = Z_NULL;
+   strm.zfree = Z_NULL;
+   strm.opaque = Z_NULL;
+
+   int ret = deflateInit2(&strm, Z_BEST_COMPRESSION, Z_DEFLATED, gzipFormat ? (15 + 16) : 15, 8, Z_DEFAULT_STRATEGY);
+   if (ret != Z_OK)
+      return ret;
+
+   /* compress until end of file */
+   BYTE in[16384];
+   BYTE out[16384];
+   int flush;
+   do
+   {
+      strm.avail_in = static_cast<uInt>(fread(in, 1, 16384, source));
+      if (ferror(source)) 
+      {
+         deflateEnd(&strm);
+         return Z_ERRNO;
+      }
+      flush = feof(source) ? Z_FINISH : Z_NO_FLUSH;
+      strm.next_in = in;
+
+      do 
+      {
+         strm.avail_out = 16384;
+         strm.next_out = out;
+         ret = deflate(&strm, flush);
+         if (ret == Z_STREAM_ERROR)
+         {
+            deflateEnd(&strm);
+            return ret;
+         }
+         int bytesOut = 16384 - strm.avail_out;
+         if ((fwrite(out, 1, bytesOut, dest) != bytesOut) || ferror(dest)) 
+         {
+            deflateEnd(&strm);
+            return Z_ERRNO;
+         }
+      } while(strm.avail_out == 0);
+   } while (flush != Z_FINISH);
+
+   deflateEnd(&strm);
+   return Z_OK;
+}
+
+/**
+ * Deflate given file
+ */
+bool LIBNETXMS_EXPORTABLE DeflateFile(const TCHAR *inputFile, const TCHAR *outputFile)
+{
+   TCHAR realOutputFile[MAX_PATH];
+   if (outputFile != NULL)
+      _tcslcpy(realOutputFile, outputFile, MAX_PATH);
+   else
+      _sntprintf(realOutputFile, MAX_PATH, _T("%s.gz"), inputFile);
+
+#ifdef _WIN32
+   FILE *in = _tfopen(inputFile, _T("rb"));
+#else
+   FILE *in = _tfopen(inputFile, _T("r"));
+#endif
+   if (in == NULL)
+      return false;
+
+#ifdef _WIN32
+   FILE *out = _tfopen(realOutputFile, _T("wb"));
+#else
+   FILE *out = _tfopen(realOutputFile, _T("w"));
+#endif
+   if (out == NULL)
+   {
+      fclose(in);
+      return false;
+   }
+
+   int rc = DeflateFileStream(in, out, true);
+
+   fclose(in);
+   fclose(out);
+   return rc == Z_OK;
+}
index 93053dc..3763c56 100644 (file)
@@ -143,10 +143,21 @@ static void CreateMiniDump(DWORD pid)
          usi.UserStreamCount = 1;
          usi.UserStreamArray = &us;
 
          usi.UserStreamCount = 1;
          usi.UserStreamArray = &us;
 
-                       MiniDumpWriteDump(hProcess, pid, hFile, 
-               static_cast<MINIDUMP_TYPE>(MiniDumpWithFullMemory | MiniDumpWithHandleData | MiniDumpWithProcessThreadData), NULL, &usi, NULL);
-                       CloseHandle(hFile);
-                       _tprintf(_T("INFO: Minidump created successfully\n"));
+                       if (MiniDumpWriteDump(hProcess, pid, hFile, 
+                   static_cast<MINIDUMP_TYPE>(MiniDumpWithFullMemory | MiniDumpWithHandleData | MiniDumpWithProcessThreadData),
+                   NULL, &usi, NULL))
+         {
+                       CloseHandle(hFile);
+            if (DeflateFile(fname))
+               DeleteFile(fname);
+                       _tprintf(_T("INFO: Minidump created successfully\n"));
+         }
+         else
+         {
+                       CloseHandle(hFile);
+            DeleteFile(fname);
+                       _tprintf(_T("INFO: Minidump creation failed\n"));
+         }
                }
                else
                {
                }
                else
                {