/ Check-in [7fca5a28]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add error logging to native Win32 heap support.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | winNativeHeap
Files: files | file ages | folders
SHA1: 7fca5a284cded6d7531060da6e99a57aed50cf8f
User & Date: mistachkin 2011-08-24 17:42:22
Context
2011-08-25
01:16
Make sure that SQLITE_FCNTL_SIZE_HINT on Windows does not shrink the file. check-in: d4f6437f user: mistachkin tags: winNativeHeap
2011-08-24
17:42
Add error logging to native Win32 heap support. check-in: 7fca5a28 user: mistachkin tags: winNativeHeap
16:13
Experimental work to allow SQLite to use the native Win32 heap API. check-in: bf3d0ab5 user: mistachkin tags: winNativeHeap
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to Makefile.msc.

    48     48   #
    49     49   TCC = $(TCC) -D_CRT_SECURE_NO_DEPRECATE -D_CRT_SECURE_NO_WARNINGS
    50     50   
    51     51   #
    52     52   # Use native Win32 heap.
    53     53   #
    54     54   TCC = $(TCC) -DSQLITE_WIN32_MALLOC=1
           55  +# TCC = $(TCC) -DSQLITE_WIN32_MALLOC_VALIDATE=1
    55     56   
    56     57   # The locations of the Tcl header and library files.  Also, the library that
    57     58   # non-stubs enabled programs using Tcl must link against.  These variables
    58     59   # (TCLINCDIR, TCLLIBDIR, and LIBTCL) may be overridden via the environment
    59     60   # prior to running nmake in order to match the actual installed location and
    60     61   # version on this machine.
    61     62   #

Changes to src/os_win.c.

   150    150     BOOL bOwned;  /* Do we own the heap (i.e. destroy it on shutdown)? */
   151    151   };
   152    152   
   153    153   #define WINMEM_MAGIC     0x42b2830b
   154    154   
   155    155   static struct winMemData win_mem_data = { WINMEM_MAGIC, NULL, FALSE };
   156    156   
          157  +#define winMemAssertMagic() assert( win_mem_data.magic==WINMEM_MAGIC )
          158  +#define winMemGetHeap() win_mem_data.hHeap
          159  +
   157    160   static void *winMemMalloc(int nBytes);
   158    161   static void winMemFree(void *pPrior);
   159    162   static void *winMemRealloc(void *pPrior, int nBytes);
   160    163   static int winMemSize(void *p);
   161    164   static int winMemRoundup(int n);
   162    165   static int winMemInit(void *pAppData);
   163    166   static void winMemShutdown(void *pAppData);
................................................................................
   218    221   
   219    222   #ifdef SQLITE_WIN32_MALLOC
   220    223   /*
   221    224   ** Allocate nBytes of memory.
   222    225   */
   223    226   static void *winMemMalloc(int nBytes){
   224    227     HANDLE hHeap;
          228  +  void *p;
   225    229   
   226         -  assert( win_mem_data.magic==WINMEM_MAGIC );
   227         -  hHeap = win_mem_data.hHeap;
          230  +  winMemAssertMagic();
          231  +  hHeap = winMemGetHeap();
   228    232     assert( hHeap!=0 );
   229    233     assert( hHeap!=INVALID_HANDLE_VALUE );
   230    234   #ifdef SQLITE_WIN32_MALLOC_VALIDATE
   231    235     assert ( HeapValidate(hHeap, 0, NULL) );
   232    236   #endif
   233    237     assert( nBytes>=0 );
   234         -  return HeapAlloc(hHeap, 0, (SIZE_T)nBytes);
          238  +  p = HeapAlloc(hHeap, 0, (SIZE_T)nBytes);
          239  +  if( !p ){
          240  +    sqlite3_log(SQLITE_NOMEM, "failed to HeapAlloc %u bytes (%d), heap=%p",
          241  +        nBytes, GetLastError(), (void*)hHeap);
          242  +  }
          243  +  return p;
   235    244   }
   236    245   
   237    246   /*
   238    247   ** Free memory.
   239    248   */
   240    249   static void winMemFree(void *pPrior){
   241    250     HANDLE hHeap;
   242    251   
   243         -  assert( win_mem_data.magic==WINMEM_MAGIC );
   244         -  hHeap = win_mem_data.hHeap;
          252  +  winMemAssertMagic();
          253  +  hHeap = winMemGetHeap();
   245    254     assert( hHeap!=0 );
   246    255     assert( hHeap!=INVALID_HANDLE_VALUE );
   247    256   #ifdef SQLITE_WIN32_MALLOC_VALIDATE
   248    257     assert ( HeapValidate(hHeap, 0, pPrior) );
   249    258   #endif
   250         -  if (!pPrior) return; /* Passing NULL to HeapFree is undefined. */
   251         -  HeapFree(hHeap, 0, pPrior);
          259  +  if( !pPrior ) return; /* Passing NULL to HeapFree is undefined. */
          260  +  if( !HeapFree(hHeap, 0, pPrior) ){
          261  +    sqlite3_log(SQLITE_NOMEM, "failed to HeapFree block %p (%d), heap=%p",
          262  +        pPrior, GetLastError(), (void*)hHeap);
          263  +  }
   252    264   }
   253    265   
   254    266   /*
   255    267   ** Change the size of an existing memory allocation
   256    268   */
   257    269   static void *winMemRealloc(void *pPrior, int nBytes){
   258    270     HANDLE hHeap;
          271  +  void *p;
   259    272   
   260         -  assert( win_mem_data.magic==WINMEM_MAGIC );
   261         -  hHeap = win_mem_data.hHeap;
          273  +  winMemAssertMagic();
          274  +  hHeap = winMemGetHeap();
   262    275     assert( hHeap!=0 );
   263    276     assert( hHeap!=INVALID_HANDLE_VALUE );
   264    277   #ifdef SQLITE_WIN32_MALLOC_VALIDATE
   265    278     assert ( HeapValidate(hHeap, 0, pPrior) );
   266    279   #endif
   267    280     assert( nBytes>=0 );
   268         -  if (!pPrior) return HeapAlloc(hHeap, 0, (SIZE_T)nBytes);
   269         -  return HeapReAlloc(hHeap, 0, pPrior, (SIZE_T)nBytes);
          281  +  if( !pPrior ){
          282  +    p = HeapAlloc(hHeap, 0, (SIZE_T)nBytes);
          283  +  }else{
          284  +    p = HeapReAlloc(hHeap, 0, pPrior, (SIZE_T)nBytes);
          285  +  }
          286  +  if( !p ){
          287  +    sqlite3_log(SQLITE_NOMEM, "failed to %s %u bytes (%d), heap=%p",
          288  +        pPrior ? "HeapReAlloc" : "HeapAlloc", nBytes, GetLastError(),
          289  +        (void*)hHeap);
          290  +  }
          291  +  return p;
   270    292   }
   271    293   
   272    294   /*
   273    295   ** Return the size of an outstanding allocation, in bytes.
   274    296   */
   275    297   static int winMemSize(void *p){
   276    298     HANDLE hHeap;
   277    299     SIZE_T n;
   278    300   
   279         -  assert( win_mem_data.magic==WINMEM_MAGIC );
   280         -  hHeap = win_mem_data.hHeap;
          301  +  winMemAssertMagic();
          302  +  hHeap = winMemGetHeap();
   281    303     assert( hHeap!=0 );
   282    304     assert( hHeap!=INVALID_HANDLE_VALUE );
   283    305   #ifdef SQLITE_WIN32_MALLOC_VALIDATE
   284    306     assert ( HeapValidate(hHeap, 0, NULL) );
   285    307   #endif
   286         -  if (!p) return 0;
          308  +  if( !p ) return 0;
   287    309     n = HeapSize(hHeap, 0, p);
   288         -  assert( n<=INT_MAX );
          310  +  if( n==(SIZE_T)-1 ){
          311  +    sqlite3_log(SQLITE_NOMEM, "failed to HeapSize block %p (%d), heap=%p",
          312  +        p, GetLastError(), (void*)hHeap);
          313  +    return 0;
          314  +  }
   289    315     return (int)n;
   290    316   }
   291    317   
   292    318   /*
   293    319   ** Round up a request size to the next valid allocation size.
   294    320   */
   295    321   static int winMemRoundup(int n){
................................................................................
   298    324   
   299    325   /*
   300    326   ** Initialize this module.
   301    327   */
   302    328   static int winMemInit(void *pAppData){
   303    329     winMemData *pWinMemData = (winMemData *)pAppData;
   304    330   
   305         -  if (!pWinMemData) return SQLITE_ERROR;
          331  +  if( !pWinMemData ) return SQLITE_ERROR;
   306    332     assert( pWinMemData->magic==WINMEM_MAGIC );
   307         -  if (!pWinMemData->hHeap){
          333  +  if( !pWinMemData->hHeap ){
   308    334       pWinMemData->hHeap = HeapCreate(0, SQLITE_WIN32_HEAP_INIT_SIZE,
   309    335                                       SQLITE_WIN32_HEAP_MAX_SIZE);
   310         -    if (!pWinMemData->hHeap){
          336  +    if( !pWinMemData->hHeap ){
          337  +      sqlite3_log(SQLITE_NOMEM,
          338  +          "failed to HeapCreate (%d), initSize=%u, maxSize=%u",
          339  +          GetLastError(), SQLITE_WIN32_HEAP_INIT_SIZE,
          340  +          SQLITE_WIN32_HEAP_MAX_SIZE);
   311    341         return SQLITE_NOMEM;
   312    342       }
   313    343       pWinMemData->bOwned = TRUE;
   314    344     }
   315    345     assert( pWinMemData->hHeap!=0 );
   316    346     assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
   317    347   #ifdef SQLITE_WIN32_MALLOC_VALIDATE
................................................................................
   322    352   
   323    353   /*
   324    354   ** Deinitialize this module.
   325    355   */
   326    356   static void winMemShutdown(void *pAppData){
   327    357     winMemData *pWinMemData = (winMemData *)pAppData;
   328    358   
   329         -  if (!pWinMemData) return;
   330         -  if (pWinMemData->hHeap){
          359  +  if( !pWinMemData ) return;
          360  +  if( pWinMemData->hHeap ){
   331    361       assert( pWinMemData->hHeap!=INVALID_HANDLE_VALUE );
   332    362   #ifdef SQLITE_WIN32_MALLOC_VALIDATE
   333    363       assert( HeapValidate(pWinMemData->hHeap, 0, NULL) );
   334    364   #endif
   335         -    if (pWinMemData->bOwned){
   336         -      if (!HeapDestroy(pWinMemData->hHeap)){
   337         -        /* TODO: Log this? */
          365  +    if( pWinMemData->bOwned ){
          366  +      if( !HeapDestroy(pWinMemData->hHeap) ){
          367  +        sqlite3_log(SQLITE_NOMEM, "failed to HeapDestroy (%d), heap=%p",
          368  +            GetLastError(), (void*)pWinMemData->hHeap);
   338    369         }
   339    370         pWinMemData->bOwned = FALSE;
   340    371       }
   341    372       pWinMemData->hHeap = NULL;
   342    373     }
   343    374   }
   344    375