debug.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 11k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. //*************************************************************
  2. //  File name:    DEBUG.C
  3. //
  4. //  Description:  Debug helper code for System control panel
  5. //                applet
  6. //
  7. //
  8. //  Microsoft Confidential
  9. //  Copyright (c) Microsoft Corporation 1992-1996
  10. //  All rights reserved
  11. //
  12. //*************************************************************
  13. #include "sysdm.h"
  14. ///////////////////////////////////////////////////////////////
  15. //      Constants
  16. ///////////////////////////////////////////////////////////////
  17. #ifdef DBG_CODE
  18. #define CCH_LABEL (sizeof(DWORD) * 2)   // 64 BITS == 8 ANSI chars
  19. #define CB_TAG     sizeof(DWORD)
  20. #define DW_TAG      ((DWORD)(0x44535953))   // 'SYSD'
  21. #define DW_TAG2     ((DWORD)(0x444F4F47))   // 'GOOD'
  22. #define CH_FILL     '*'
  23. ///////////////////////////////////////////////////////////////
  24. //      Structures and Types
  25. ///////////////////////////////////////////////////////////////
  26. /*
  27.  * NOTE!!!!
  28.  *
  29.  * The HOBJHDR structure MUST be a multiple of 8 bytes (64bits) in len!
  30.  * otherwise this code will *FAULT* on ALPHA machines!
  31.  *
  32.  */
  33. typedef struct HHO *PHHO;
  34. struct HHO {
  35.     PHHO    phhoNext;
  36.     PHHO    phhoPrev;
  37.     CHAR    szFile[CCH_LABEL];
  38.     DWORD   iLine;
  39.     DWORD   cBytesData;
  40.     DWORD   dwTmp;
  41.     DWORD   dwTag2;
  42. };
  43. typedef struct HHO HOBJHDR;
  44. typedef struct {
  45.     LPVOID  pvPtr;
  46.     CHAR    szFile[CCH_LABEL];
  47.     DWORD   iLine;
  48.     CHAR    szFreedBy[CCH_LABEL];
  49.     DWORD   iLineFreed;
  50. } FREELOGREC, *PFREELOGREC;
  51. ///////////////////////////////////////////////////////////////
  52. //      Global variables
  53. ///////////////////////////////////////////////////////////////
  54. /*
  55.  * Root of memory chain
  56.  */
  57. HOBJHDR hhoRoot = { &hhoRoot, &hhoRoot, { 'R', 'O', 'O', 'T' }, 0, sizeof(hhoRoot) };
  58. /*
  59.  * Buffer used for OutputDebugString formatting (See DbgPrintf and DbgStopX)
  60.  */
  61. TCHAR szDbgOutBuffer[1024];
  62. /*
  63.  * Buffer used for logging
  64.  */
  65. #define CFLR_MAX    1024
  66. FREELOGREC aflrFreeLog[CFLR_MAX];
  67. PFREELOGREC g_pflrUnused = NULL;
  68. #define NextFreeLogRec( pflr )    ((pflr >= &aflrFreeLog[CFLR_MAX-1]) ? aflrFreeLog : pflr+1)
  69. #define PrevFreeLogRec( pflr )    ((pflr <= aflrFreeLog) ? &aflrFreeLog[CFLR_MAX-1] : pflr-1)
  70. //***************************************************************
  71. //
  72. // void DbgPrintf( LPTSTR szFmt, ... )
  73. //
  74. //  Formatted version of OutputDebugString
  75. //
  76. //  Parameters: Same as printf()
  77. //
  78. //  History:
  79. //      18-Jan-1996 JonPa       Wrote it
  80. //***************************************************************
  81. void DbgPrintf( LPTSTR szFmt, ... ) {
  82.     va_list marker;
  83.     va_start( marker, szFmt );
  84.     wvsprintf( szDbgOutBuffer, szFmt, marker );
  85.     OutputDebugString( szDbgOutBuffer );
  86.     va_end( marker );
  87. }
  88. //***************************************************************
  89. //
  90. // void DbgStopX(LPSTR mszFile, int iLine, LPTSTR szText )
  91. //
  92. //  Print a string (with location id) and then break
  93. //
  94. //  Parameters:
  95. //      mszFile     ANSI filename (__FILE__)
  96. //      iLine       line number   (__LINE__)
  97. //      szText      Text string to send to debug port
  98. //
  99. //  History:
  100. //      18-Jan-1996 JonPa       Wrote it
  101. //***************************************************************
  102. void DbgStopX(LPSTR mszFile, int iLine, LPTSTR szText ) {
  103.     int cch;
  104.     wsprintf( szDbgOutBuffer, TEXT("SYSDM.CPL (%hs %d) : %sn"), mszFile, iLine, szText );
  105.     OutputDebugString(szDbgOutBuffer);
  106.     DebugBreak();
  107. }
  108. //***************************************************************
  109. //
  110. // void MemAllocWorker(LPSTR szFile, int iLine, UINT uFlags, UINT cBytes)
  111. //
  112. //  Debug replacement for LocalAlloc
  113. //
  114. //  Parameters:
  115. //      mszFile     ANSI filename (__FILE__)
  116. //      iLine       line number   (__LINE__)
  117. //      uFlags      same as LocalAlloc
  118. //      cBytes      same as LocalAlloc
  119. //
  120. //  History:
  121. //      18-Jan-1996 JonPa       Wrote it
  122. //***************************************************************
  123. HLOCAL MemAllocWorker(LPSTR szFile, int iLine, UINT uFlags, UINT cBytes) {
  124.     PHHO phhoNew;
  125.     HLOCAL hMem;
  126.     LPSTR psz;
  127.     UINT i, cBytesAlloc;
  128.     cBytesAlloc = cBytes;
  129.     //
  130.     // If fixed alloc...
  131.     //
  132.     if ((uFlags & (LMEM_MOVEABLE | LMEM_DISCARDABLE)) != 0) {
  133.         DBGSTOPX( szFile, iLine, "Attempting to allocate movable memory... Returning NULL");
  134.         return NULL;
  135.     }
  136.     cBytesAlloc = cBytes + sizeof(HOBJHDR);
  137.     // DWORD align Tag
  138.     cBytesAlloc = ((cBytesAlloc + 3) & ~3);
  139.     cBytesAlloc += CB_TAG;
  140.     hMem = LocalAlloc( uFlags, cBytesAlloc );
  141.     //
  142.     // If a valid pointer, and it is a fixed pointer...
  143.     //
  144.     phhoNew = (PHHO)hMem;
  145.     if (hMem != NULL) {
  146.         phhoNew->phhoNext = hhoRoot.phhoNext;
  147.         hhoRoot.phhoNext = phhoNew;
  148.         phhoNew->phhoNext->phhoPrev = phhoNew;
  149.         phhoNew->phhoPrev = &hhoRoot;
  150.         phhoNew->dwTag2 = DW_TAG2;
  151.         for( psz = szFile; *psz != ''; psz++ );
  152.         for( ; psz != szFile && *psz != ':' && *psz != '/' && *psz != '\'; psz--);
  153.         if (*psz == ':' || *psz == '/' || *psz == '\')
  154.             psz++;
  155.         for( i = 0; i < CCH_LABEL; i++ ) {
  156.             phhoNew->szFile[i] = *psz;
  157.             if (*psz) {
  158.                 psz++;
  159.             }
  160.         }
  161.         phhoNew->iLine = iLine;
  162.         phhoNew->cBytesData = cBytes;
  163.         phhoNew += 1;   // point phhoNew to 1st byte after structure
  164.         // round up to nearest DWORD
  165.         { LPBYTE pb = (LPBYTE)phhoNew + cBytes;
  166.             cBytesAlloc -= CB_TAG;
  167.             cBytes += sizeof(HOBJHDR);
  168.             while( cBytes < cBytesAlloc ) {
  169.                 *pb++ = CH_FILL;
  170.                 cBytes++;
  171.             }
  172.             *((LPDWORD)pb) = DW_TAG;
  173.         }
  174.     }
  175.     return (HLOCAL)phhoNew;
  176. }
  177. //***************************************************************
  178. //
  179. // void MemFreeWorker( LPSTR szFile, int iLine, HLOCAL hMem )
  180. //
  181. //  Debug replacement for LocalFree
  182. //
  183. //  Parameters:
  184. //      mszFile     ANSI filename (__FILE__)
  185. //      iLine       line number   (__LINE__)
  186. //      hMem        same as LocalAlloc
  187. //
  188. //  History:
  189. //      18-Jan-1996 JonPa       Wrote it
  190. //***************************************************************
  191. HLOCAL MemFreeWorker( LPSTR szFile, int iLine, HLOCAL hMem ) {
  192.     PHHO phhoMem;
  193.     UINT uFlags;
  194.     UINT cBytes, cBytesAlloc;
  195.     LPSTR psz;
  196.     INT  i;
  197.     if (g_pflrUnused == NULL) {
  198.         ZeroMemory( aflrFreeLog, sizeof(aflrFreeLog) );
  199.         g_pflrUnused = aflrFreeLog;
  200.     }
  201.     if (hMem == NULL) {
  202.         DBGSTOPX( szFile, iLine, "Freeing NULL handle!");
  203.         return LocalFree(hMem);
  204.     }
  205.     phhoMem = (PHHO)hMem - 1;
  206.     if (phhoMem->dwTag2 != DW_TAG2) {
  207.         PFREELOGREC pflr;
  208.         //
  209.         // Our tag has been stompped on, see if we have already freed this object
  210.         //
  211.         for( pflr = PrevFreeLogRec(g_pflrUnused); pflr != g_pflrUnused; pflr = PrevFreeLogRec(pflr) ) {
  212.             if (pflr->pvPtr == phhoMem) {
  213.                 DBGPRINTF((TEXT("SYSDM.CPL: Object may have already been freed by %.8hs line %dn(that obj was allocated by %.8hs line %d)n"),
  214.                     pflr->szFreedBy, pflr->iLineFreed, pflr->szFile, pflr->iLine));
  215.                 break;
  216.             }
  217.         }
  218.         DBGPRINTF((TEXT("SYSDM.CPL: Trashed memory object was allocated in %.8hs line %d (%d bytes)n"), phhoMem->szFile, phhoMem->iLine, phhoMem->cBytesData));
  219.         DBGSTOPX( szFile, iLine, "Either heap object trashed or not allocated object");
  220.     }
  221.     cBytes = phhoMem->cBytesData;
  222. #if 0
  223.     if (cBytes < 0) {
  224.         // Not our object?
  225.         DBGSTOPX( szFile, iLine, "Either heap object trashed or not allocated object");
  226.         return LocalFree(hMem);
  227.     }
  228. #endif
  229.     cBytes += sizeof(HOBJHDR);
  230.     // DWORD align
  231.     cBytesAlloc = (cBytes + 3) & ~3;
  232.     { LPBYTE pb = (LPBYTE)(phhoMem);
  233.         pb += cBytes;
  234.         while( cBytes < cBytesAlloc ) {
  235.             if (*pb++ != CH_FILL) {
  236.                 DBGPRINTF((TEXT("SYSDM.CPL: Trashed memory object was allocated in %.8hs line %d (%d bytes)n"),
  237.                         phhoMem->szFile, phhoMem->iLine, phhoMem->cBytesData));
  238.                 DBGSTOPX( szFile, iLine, "End of structure overwritten");
  239.             }
  240.             cBytes++;
  241.         }
  242.         if (*((LPDWORD)pb) != DW_TAG) {
  243.             DBGSTOPX( szFile, iLine, "Freeing structure that was not allocated!");
  244.             // Not our structure
  245.             return LocalFree(hMem);
  246.         }
  247.     }
  248.     // Our structure, check header
  249.     if (phhoMem->phhoNext->phhoPrev != phhoMem || phhoMem->phhoPrev->phhoNext != phhoMem ) {
  250.         DBGPRINTF((TEXT("SYSDM.CPL: Orphaned memory object was allocated in %.8hs line %d (%d bytes)n"),
  251.                 phhoMem->szFile, phhoMem->iLine, phhoMem->cBytesData));
  252.         DBGSTOPX( szFile, iLine, "Attempting to free orphaned memory object");
  253.     }
  254.     phhoMem->phhoPrev->phhoNext = phhoMem->phhoNext;
  255.     phhoMem->phhoNext->phhoPrev = phhoMem->phhoPrev;
  256.     //
  257.     // Log this free, incase we try and free it twice
  258.     //
  259.     // Mark as freed
  260.     phhoMem->dwTag2 = 0;
  261.     // Remember who alloc'ed obj
  262.     g_pflrUnused->pvPtr = phhoMem;
  263.     CopyMemory( g_pflrUnused->szFile, phhoMem->szFile, sizeof(g_pflrUnused->szFile) );
  264.     g_pflrUnused->iLine = phhoMem->iLine;
  265.     // Remember who freed the obj
  266.     for( psz = szFile; *psz != ''; psz++ );
  267.     for( ; psz != szFile && *psz != ':' && *psz != '/' && *psz != '\'; psz--);
  268.     if (*psz == ':' || *psz == '/' || *psz == '\')
  269.         psz++;
  270.     for( i = 0; i < CCH_LABEL; i++ ) {
  271.         g_pflrUnused->szFreedBy[i] = *psz;
  272.         if (*psz) {
  273.             psz++;
  274.         }
  275.     }
  276.     g_pflrUnused->iLineFreed = iLine;
  277.     // Point roaming ptr to next record and mark as unused
  278.     g_pflrUnused = NextFreeLogRec(g_pflrUnused);
  279.     ZeroMemory( g_pflrUnused, sizeof(*g_pflrUnused) );
  280.     return LocalFree(phhoMem);
  281. }
  282. //***************************************************************
  283. //
  284. //  void MemExitCheckWorker() {
  285. //
  286. //  Debug replacement for LocalFree
  287. //
  288. //  Parameters:
  289. //      mszFile     ANSI filename (__FILE__)
  290. //      iLine       line number   (__LINE__)
  291. //      hMem        same as LocalAlloc
  292. //
  293. //  History:
  294. //      18-Jan-1996 JonPa       Wrote it
  295. //***************************************************************
  296. void MemExitCheckWorker( void ) {
  297.     PHHO phho;
  298.     for( phho = hhoRoot.phhoNext; phho != &hhoRoot; phho = phho->phhoNext ) {
  299.         DBGPRINTF((TEXT("SYSDM.CPL: Exiting with out freeing object allocated in %.8hs line %d (%d bytes)n"),
  300.                 phho->szFile, phho->iLine, phho->cBytesData));
  301.     }
  302. }
  303. #endif // DBG_CODE