Fossil

Check-in [99cb2ccd94]
Login

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

Overview
Comment:Removed fossil_atexit_free_this() because it effectively costs more static memory than it cleans up in dynamic memory.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | memleak-fixes
Files: files | file ages | folders
SHA3-256: 99cb2ccd94b45dde65a91c1338296a98c9a6bd29ebb507ad32577b0646bb3af7
User & Date: stephan 2019-12-21 03:45:36.886
Context
2019-12-21
18:24
Moved two decls from an outer scope to the inner scope where they're used. check-in: 2576cf5fd1 user: stephan tags: memleak-fixes
03:45
Removed fossil_atexit_free_this() because it effectively costs more static memory than it cleans up in dynamic memory. check-in: 99cb2ccd94 user: stephan tags: memleak-fixes
2019-12-20
15:41
Removed the cleanup of g.zXYZ because there's simply too high of a chance that future changes would turn one of those free() calls into a double-free or passing an invalid pointer to free(). check-in: d60dd7afb0 user: stephan tags: memleak-fixes
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/db.c.
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
  if( zRepo==0 ){
    zRepo = db_lget("repository", 0);
    if( zRepo && !file_is_absolute_path(zRepo) ){
      char * zFree = zRepo;
      zRepo = mprintf("%s%s", g.zLocalRoot, zRepo);
      fossil_free(zFree);
    }
    fossil_atexit_free_this(zRepo);
  }
  return zRepo;
}

/*
** Returns non-zero if the default value for the "allow-symlinks" setting
** is "on".  When on Windows, this always returns false.







<







1630
1631
1632
1633
1634
1635
1636

1637
1638
1639
1640
1641
1642
1643
  if( zRepo==0 ){
    zRepo = db_lget("repository", 0);
    if( zRepo && !file_is_absolute_path(zRepo) ){
      char * zFree = zRepo;
      zRepo = mprintf("%s%s", g.zLocalRoot, zRepo);
      fossil_free(zFree);
    }

  }
  return zRepo;
}

/*
** Returns non-zero if the default value for the "allow-symlinks" setting
** is "on".  When on Windows, this always returns false.
Changes to src/main.c.
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
*/
#define CGIDEBUG(X)  if( g.fDebug ) cgi_debug X

#endif

Global g;

/*
** Infrastructure for fossil_atexit_free_this().
*/
static struct {
  void* list[20];  /* Pointers to pass to fossil_free() during
                    ** atexit(). */
  int n;            /* Number of items currently in this->list. */
} fossilFreeAtExit = { {0}, 0 };

/*
** If zMem is not NULL and there is space in fossil's atexit cleanup
** queue, zMem is added to that queue so that it will be passed to
** fossil_free() during the atexit() phase of app shutdown. If the
** queue is full or zMem is NULL, this function has no side effects.
**
** This is intended to be called by routines which allocate heap
** memory for static-scope values which otherwise won't be freed, and
** the static queue size is relatively small.
*/
void fossil_atexit_free_this(void * zMem){
  if(zMem!=0
     && fossilFreeAtExit.n < (sizeof(fossilFreeAtExit.list)
                              / sizeof(fossilFreeAtExit.list[0]))){
    fossilFreeAtExit.list[fossilFreeAtExit.n++] = zMem;
  }
}

/*
** atexit() handler which frees up "some" of the resources
** used by fossil.
*/
static void fossil_atexit(void) {
  static int once = 0;
  if( once++ ) return; /* Ensure that this routine only runs once */







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







321
322
323
324
325
326
327



























328
329
330
331
332
333
334
*/
#define CGIDEBUG(X)  if( g.fDebug ) cgi_debug X

#endif

Global g;




























/*
** atexit() handler which frees up "some" of the resources
** used by fossil.
*/
static void fossil_atexit(void) {
  static int once = 0;
  if( once++ ) return; /* Ensure that this routine only runs once */
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
#endif
  if(g.db){
    db_close(0);
  }
  manifest_clear_cache();
  content_clear_cache(1);
  rebuild_clear_cache();
  if(fossilFreeAtExit.n>0){
    int i;
    for(i = 0; i < fossilFreeAtExit.n; ++i){
      fossil_free(fossilFreeAtExit.list[i]);
      fossilFreeAtExit.list[i] = 0;
    }
    fossilFreeAtExit.n = 0;
  }
  /*
  ** FIXME: The next two lines cannot always be enabled; however, they
  **        are very useful for tracking down TH1 memory leaks.
  */
  if( fossil_getenv("TH1_DELETE_INTERP")!=0 ){
    if( g.interp ){
      Th_DeleteInterp(g.interp); g.interp = 0;







<
<
<
<
<
<
<
<







364
365
366
367
368
369
370








371
372
373
374
375
376
377
#endif
  if(g.db){
    db_close(0);
  }
  manifest_clear_cache();
  content_clear_cache(1);
  rebuild_clear_cache();








  /*
  ** FIXME: The next two lines cannot always be enabled; however, they
  **        are very useful for tracking down TH1 memory leaks.
  */
  if( fossil_getenv("TH1_DELETE_INTERP")!=0 ){
    if( g.interp ){
      Th_DeleteInterp(g.interp); g.interp = 0;
Changes to src/manifest.c.
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963

  blob_zero(&comment);
  blob_zero(&brief);
  if( once ){
    once = 0;
    zTitleExpr = db_get("ticket-title-expr", "title");
    zStatusColumn = db_get("ticket-status-column", "status");
    fossil_atexit_free_this(zTitleExpr);
    fossil_atexit_free_this(zStatusColumn);
  }
  zTitle = db_text("unknown",
    "SELECT \"%w\" FROM ticket WHERE tkt_uuid=%Q",
    zTitleExpr, pManifest->zTicketUuid
  );
  if( !isNew ){
    for(i=0; i<pManifest->nField; i++){







<
<







1948
1949
1950
1951
1952
1953
1954


1955
1956
1957
1958
1959
1960
1961

  blob_zero(&comment);
  blob_zero(&brief);
  if( once ){
    once = 0;
    zTitleExpr = db_get("ticket-title-expr", "title");
    zStatusColumn = db_get("ticket-status-column", "status");


  }
  zTitle = db_text("unknown",
    "SELECT \"%w\" FROM ticket WHERE tkt_uuid=%Q",
    zTitleExpr, pManifest->zTicketUuid
  );
  if( !isNew ){
    for(i=0; i<pManifest->nField; i++){