/ Check-in [bf98cf82]
Login

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

Overview
Comment:remove all memory leaks (CVS 80)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: bf98cf82a73c54c4eced04994bb1a019844dfc03
User & Date: drh 2000-06-08 13:36:40
Context
2000-06-08
15:10
:-) (CVS 81) check-in: 61c381e7 user: drh tags: trunk
13:36
remove all memory leaks (CVS 80) check-in: bf98cf82 user: drh tags: trunk
11:25
:-) (CVS 79) check-in: 305b043f user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/build.c.

    29     29   **     DROP TABLE
    30     30   **     CREATE INDEX
    31     31   **     DROP INDEX
    32     32   **     creating expressions and ID lists
    33     33   **     COPY
    34     34   **     VACUUM
    35     35   **
    36         -** $Id: build.c,v 1.16 2000/06/07 23:51:50 drh Exp $
           36  +** $Id: build.c,v 1.17 2000/06/08 13:36:40 drh Exp $
    37     37   */
    38     38   #include "sqliteInt.h"
    39     39   
    40     40   /*
    41     41   ** This routine is called after a single SQL statement has been
    42     42   ** parsed and we want to execute the code to implement 
    43     43   ** the statement.  Prior action routines should have already
................................................................................
   187    187       sqliteFree(pTable->aCol[i].zName);
   188    188       sqliteFree(pTable->aCol[i].zDflt);
   189    189     }
   190    190     for(pIndex = pTable->pIndex; pIndex; pIndex=pNext){
   191    191       pNext = pIndex->pNext;
   192    192       sqliteDeleteIndex(db, pIndex);
   193    193     }
          194  +  sqliteFree(pTable->zName);
   194    195     sqliteFree(pTable->aCol);
   195    196     sqliteFree(pTable);
   196    197   }
   197    198   
   198    199   /*
   199    200   ** Construct the name of a user table from a token.
   200    201   **
   201    202   ** Space to hold the name is obtained from sqliteMalloc() and must
   202    203   ** be freed by the calling function.
   203    204   */
   204    205   char *sqliteTableNameFromToken(Token *pName){
   205         -  char *zName = 0;
   206         -  sqliteSetNString(&zName, pName->z, pName->n, 0);
          206  +  char *zName = sqliteStrNDup(pName->z, pName->n);
   207    207     sqliteDequote(zName);
   208    208     return zName;
   209    209   }
   210    210   
   211    211   /*
   212    212   ** Begin constructing a new table representation in memory.  This is
   213    213   ** the first of several action routines that get called in response

Changes to src/expr.c.

    19     19   ** Author contact information:
    20     20   **   drh@hwaci.com
    21     21   **   http://www.hwaci.com/drh/
    22     22   **
    23     23   *************************************************************************
    24     24   ** This file contains C code routines used for processing expressions
    25     25   **
    26         -** $Id: expr.c,v 1.12 2000/06/08 11:25:01 drh Exp $
           26  +** $Id: expr.c,v 1.13 2000/06/08 13:36:40 drh Exp $
    27     27   */
    28     28   #include "sqliteInt.h"
    29     29   
    30     30   /*
    31     31   ** Walk an expression tree.  Return 1 if the expression is constant
    32     32   ** and 0 if it involves variables.
    33     33   */
................................................................................
   114    114   int sqliteExprResolveIds(Parse *pParse, IdList *pTabList, Expr *pExpr){
   115    115     if( pExpr==0 ) return 0;
   116    116     switch( pExpr->op ){
   117    117       /* A lone identifier */
   118    118       case TK_ID: {
   119    119         int cnt = 0;   /* Number of matches */
   120    120         int i;         /* Loop counter */
   121         -      char *z = 0;
   122         -      sqliteSetNString(&z, pExpr->token.z, pExpr->token.n, 0);
          121  +      char *z = sqliteStrNDup(pExpr->token.z, pExpr->token.n);
   123    122         for(i=0; i<pTabList->nId; i++){
   124    123           int j;
   125    124           Table *pTab = pTabList->a[i].pTab;
   126    125           if( pTab==0 ) continue;
   127    126           for(j=0; j<pTab->nCol; j++){
   128    127             if( sqliteStrICmp(pTab->aCol[j].zName, z)==0 ){
   129    128               cnt++;
................................................................................
   155    154         Expr *pLeft, *pRight;    /* Left and right subbranches of the expr */
   156    155         char *zLeft, *zRight;    /* Text of an identifier */
   157    156   
   158    157         pLeft = pExpr->pLeft;
   159    158         pRight = pExpr->pRight;
   160    159         assert( pLeft && pLeft->op==TK_ID );
   161    160         assert( pRight && pRight->op==TK_ID );
   162         -      zLeft = 0;
   163         -      sqliteSetNString(&zLeft, pLeft->token.z, pLeft->token.n, 0);
   164         -      zRight = 0;
   165         -      sqliteSetNString(&zRight, pRight->token.z, pRight->token.n, 0);
          161  +      zLeft = sqliteStrNDup(pLeft->token.z, pLeft->token.n);
          162  +      zRight = sqliteStrNDup(pRight->token.z, pRight->token.n);
   166    163         for(i=0; i<pTabList->nId; i++){
   167    164           int j;
   168    165           char *zTab;
   169    166           Table *pTab = pTabList->a[i].pTab;
   170    167           if( pTab==0 ) continue;
   171    168           if( pTabList->a[i].zAlias ){
   172    169             zTab = pTabList->a[i].zAlias;
................................................................................
   508    505         sqliteExprCode(pParse, pExpr->pLeft);
   509    506         sqliteExprCode(pParse, pExpr->pRight);
   510    507         dest = sqliteVdbeCurrentAddr(v) + 2;
   511    508         sqliteVdbeAddOp(v, op, 0, dest, 0, 0);
   512    509         sqliteVdbeAddOp(v, OP_AddImm, -1, 0, 0, 0);
   513    510         break;
   514    511       }
   515         -    case TK_NOT:
   516    512       case TK_UMINUS: {
          513  +      assert( pExpr->pLeft );
          514  +      if( pExpr->pLeft->op==TK_INTEGER ){
          515  +        int i = atoi(pExpr->pLeft->token.z);
          516  +        sqliteVdbeAddOp(v, OP_Integer, -i, 0, 0, 0);
          517  +        break;
          518  +      }else if( pExpr->pLeft->op==TK_FLOAT ){
          519  +        Token *p = &pExpr->pLeft->token;
          520  +        char *z = sqliteMalloc( p->n + 2 );
          521  +        sprintf(z, "-%.*s", p->n, p->z);
          522  +        sqliteVdbeAddOp(v, OP_String, 0, 0, z, 0);
          523  +        sqliteFree(z);
          524  +        break;
          525  +      }
          526  +      /* Fall true into TK_NOT */
          527  +    }
          528  +    case TK_NOT: {
   517    529         sqliteExprCode(pParse, pExpr->pLeft);
   518    530         sqliteVdbeAddOp(v, op, 0, 0, 0, 0);
   519    531         break;
   520    532       }
   521    533       case TK_ISNULL:
   522    534       case TK_NOTNULL: {
   523    535         int dest;

Changes to src/parse.y.

    22     22   **
    23     23   *************************************************************************
    24     24   ** This file contains SQLite's grammar for SQL.  Process this file
    25     25   ** using the lemon parser generator to generate C code that runs
    26     26   ** the parser.  Lemon will also generate a header file containing
    27     27   ** numeric codes for all of the tokens.
    28     28   **
    29         -** @(#) $Id: parse.y,v 1.16 2000/06/07 23:51:50 drh Exp $
           29  +** @(#) $Id: parse.y,v 1.17 2000/06/08 13:36:40 drh Exp $
    30     30   */
    31     31   %token_prefix TK_
    32     32   %token_type {Token}
    33     33   %extra_argument {Parse *pParse}
    34     34   %syntax_error {
    35     35     sqliteSetNString(&pParse->zErrMsg,"syntax error near \"",0,TOKEN.z,TOKEN.n,
    36     36                      "\"", 1, 0);
................................................................................
   267    267   %destructor item {sqliteExprDelete($$);}
   268    268   
   269    269   itemlist(A) ::= itemlist(X) COMMA item(Y).  {A = sqliteExprListAppend(X,Y,0);}
   270    270   itemlist(A) ::= item(X).     {A = sqliteExprListAppend(0,X,0);}
   271    271   item(A) ::= INTEGER(X).      {A = sqliteExpr(TK_INTEGER, 0, 0, &X);}
   272    272   item(A) ::= PLUS INTEGER(X). {A = sqliteExpr(TK_INTEGER, 0, 0, &X);}
   273    273   item(A) ::= MINUS INTEGER(X). {
   274         -  A = sqliteExpr(TK_INTEGER, 0, 0, 0);
   275         -  A->token.z = 0;
   276         -  sqliteSetNString(&A->token.z, "-", 1, X.z, X.n, 0);
          274  +  A = sqliteExpr(TK_UMINUS, 0, 0, 0);
          275  +  A->pLeft = sqliteExpr(TK_INTEGER, 0, 0, &X);
   277    276   }
   278    277   item(A) ::= FLOAT(X).        {A = sqliteExpr(TK_FLOAT, 0, 0, &X);}
   279    278   item(A) ::= PLUS FLOAT(X).   {A = sqliteExpr(TK_FLOAT, 0, 0, &X);}
   280    279   item(A) ::= MINUS FLOAT(X).  {
   281         -  A = sqliteExpr(TK_FLOAT, 0, 0, 0);
   282         -  A->token.z = 0;
   283         -  sqliteSetNString(&A->token.z, "-", 1, X.z, X.n, 0);
          280  +  A = sqliteExpr(TK_UMINUS, 0, 0, 0);
          281  +  A->pLeft = sqliteExpr(TK_FLOAT, 0, 0, &X);
   284    282   }
   285    283   item(A) ::= STRING(X).       {A = sqliteExpr(TK_STRING, 0, 0, &X);}
   286    284   item(A) ::= NULL.            {A = sqliteExpr(TK_NULL, 0, 0, 0);}
   287    285   
   288    286   %type fieldlist_opt {IdList*}
   289    287   %destructor fieldlist_opt {sqliteIdListDelete($$);}
   290    288   %type fieldlist {IdList*}

Changes to src/select.c.

    20     20   **   drh@hwaci.com
    21     21   **   http://www.hwaci.com/drh/
    22     22   **
    23     23   *************************************************************************
    24     24   ** This file contains C code routines that are called by the parser
    25     25   ** to handle SELECT statements.
    26     26   **
    27         -** $Id: select.c,v 1.21 2000/06/08 11:25:01 drh Exp $
           27  +** $Id: select.c,v 1.22 2000/06/08 13:36:40 drh Exp $
    28     28   */
    29     29   #include "sqliteInt.h"
    30     30   
    31     31   /*
    32     32   ** Allocate a new Select structure and return a pointer to that
    33     33   ** structure.
    34     34   */
................................................................................
   140    140       if( zSortOrder==0 ) return 1;
   141    141       for(i=0; i<pOrderBy->nExpr; i++){
   142    142         zSortOrder[i] = pOrderBy->a[i].sortOrder ? '-' : '+';
   143    143         sqliteExprCode(pParse, pOrderBy->a[i].pExpr);
   144    144       }
   145    145       zSortOrder[pOrderBy->nExpr] = 0;
   146    146       sqliteVdbeAddOp(v, OP_SortMakeKey, pOrderBy->nExpr, 0, zSortOrder, 0);
          147  +    sqliteFree(zSortOrder);
   147    148       sqliteVdbeAddOp(v, OP_SortPut, 0, 0, 0, 0);
   148    149     }else 
   149    150   
   150    151     /* In this mode, write each query result to the key of the temporary
   151    152     ** table iParm.
   152    153     */
   153    154     if( eDest==SRT_Union ){
................................................................................
   374    375     for(i=0; i<pOrderBy->nExpr; i++){
   375    376       Expr *pE = pOrderBy->a[i].pExpr;
   376    377       int match = 0;
   377    378       if( pOrderBy->a[i].done ) continue;
   378    379       for(j=0; j<pEList->nExpr; j++){
   379    380         if( pEList->a[i].zName && (pE->op==TK_ID || pE->op==TK_STRING) ){
   380    381           char *zName = pEList->a[i].zName;
   381         -        char *zLabel = 0;
   382         -        sqliteSetNString(&zLabel, pE->token.z, pE->token.n, 0);
          382  +        char *zLabel = sqliteStrNDup(pE->token.z, pE->token.n);
   383    383           sqliteDequote(zLabel);
   384    384           if( sqliteStrICmp(zName, zLabel)==0 ){ 
   385    385             match = 1; 
   386    386           }
          387  +        sqliteFree(zLabel);
   387    388         }
   388    389         if( match==0 && sqliteExprCompare(pE, pEList->a[i].pExpr) ){
   389    390           match = 1;
   390    391         }
   391    392         if( match ){
   392    393           pE->op = TK_FIELD;
   393    394           pE->iField = j;

Changes to src/sqliteInt.h.

    19     19   ** Author contact information:
    20     20   **   drh@hwaci.com
    21     21   **   http://www.hwaci.com/drh/
    22     22   **
    23     23   *************************************************************************
    24     24   ** Internal interface definitions for SQLite.
    25     25   **
    26         -** @(#) $Id: sqliteInt.h,v 1.22 2000/06/07 23:51:51 drh Exp $
           26  +** @(#) $Id: sqliteInt.h,v 1.23 2000/06/08 13:36:40 drh Exp $
    27     27   */
    28     28   #include "sqlite.h"
    29     29   #include "dbbe.h"
    30     30   #include "vdbe.h"
    31     31   #include "parse.h"
    32     32   #include <gdbm.h>
    33     33   #include <stdio.h>
................................................................................
    36     36   #include <assert.h>
    37     37   
    38     38   /* #define MEMORY_DEBUG 1 */
    39     39   #ifdef MEMORY_DEBUG
    40     40   # define sqliteMalloc(X)    sqliteMalloc_(X,__FILE__,__LINE__)
    41     41   # define sqliteFree(X)      sqliteFree_(X,__FILE__,__LINE__)
    42     42   # define sqliteRealloc(X,Y) sqliteRealloc_(X,Y,__FILE__,__LINE__)
           43  +# define sqliteStrDup(X)    sqliteStrDup_(X,__FILE__,__LINE__)
           44  +# define sqliteStrNDup(X,Y) sqliteStrNDup_(X,Y,__FILE__,__LINE__)
    43     45     void sqliteStrRealloc(char**);
    44     46   #else
    45     47   # define sqliteStrRealloc(X)
    46     48   #endif
    47     49   
           50  +/*
           51  +** The following global variables are used for testing and debugging
           52  +** only.  Thy only work if MEMORY_DEBUG is defined.
           53  +*/
           54  +#ifdef MEMORY_DEBUG
           55  +int sqlite_nMalloc;         /* Number of sqliteMalloc() calls */
           56  +int sqlite_nFree;           /* Number of sqliteFree() calls */
           57  +int sqlite_iMallocFail;     /* Fail sqliteMalloc() after this many calls */
           58  +#endif
           59  +
    48     60   /*
    49     61   ** The number of entries in the in-memory hash table holding the
    50     62   ** schema.
    51     63   */
    52     64   #define N_HASH        51
    53     65   
    54     66   /*
................................................................................
   302    314   int sqliteHashNoCase(const char *, int);
   303    315   int sqliteCompare(const char *, const char *);
   304    316   int sqliteSortCompare(const char *, const char *);
   305    317   #ifdef MEMORY_DEBUG
   306    318     void *sqliteMalloc_(int,char*,int);
   307    319     void sqliteFree_(void*,char*,int);
   308    320     void *sqliteRealloc_(void*,int,char*,int);
          321  +  char *sqliteStrDup_(const char*,char*,int);
          322  +  char *sqliteStrNDup_(const char*, int,char*,int);
   309    323   #else
   310    324     void *sqliteMalloc(int);
   311    325     void sqliteFree(void*);
   312    326     void *sqliteRealloc(void*,int);
          327  +  char *sqliteStrDup(const char*);
          328  +  char *sqliteStrNDup(const char*, int);
   313    329   #endif
   314    330   int sqliteGetToken(const char*, int *);
   315    331   void sqliteSetString(char **, const char *, ...);
   316    332   void sqliteSetNString(char **, ...);
   317    333   void sqliteDequote(char*);
   318    334   int sqliteRunParser(Parse*, char*, char **);
   319    335   void sqliteExec(Parse*);

Changes to src/tokenize.c.

    23     23   *************************************************************************
    24     24   ** An tokenizer for SQL
    25     25   **
    26     26   ** This file contains C code that splits an SQL input string up into
    27     27   ** individual tokens and sends those tokens one-by-one over to the
    28     28   ** parser for analysis.
    29     29   **
    30         -** $Id: tokenize.c,v 1.9 2000/06/07 02:04:23 drh Exp $
           30  +** $Id: tokenize.c,v 1.10 2000/06/08 13:36:40 drh Exp $
    31     31   */
    32     32   #include "sqliteInt.h"
    33     33   #include <ctype.h>
    34     34   #include <stdlib.h>
    35     35   
    36     36   /*
    37     37   ** All the keywords of the SQL language are stored as in a hash
................................................................................
   324    324         case TK_SPACE:
   325    325           break;
   326    326         case TK_COMMENT: {
   327    327           /* Various debugging modes can be turned on and off using
   328    328           ** special SQL comments.  Check for the special comments
   329    329           ** here and take approriate action if found.
   330    330           */
          331  +#ifndef NDEBUG
   331    332           char *z = pParse->sLastToken.z;
   332    333           if( sqliteStrNICmp(z,"--parser-trace-on--",19)==0 ){
   333    334             trace = stderr;
   334    335             sqliteParserTrace(trace, "parser: ");
   335    336           }else if( sqliteStrNICmp(z,"--parser-trace-off--", 20)==0 ){
   336    337             trace = 0;
   337    338             sqliteParserTrace(trace, "parser: ");
   338    339           }else if( sqliteStrNICmp(z,"--vdbe-trace-on--",17)==0 ){
   339    340             pParse->db->flags |= SQLITE_VdbeTrace;
   340    341           }else if( sqliteStrNICmp(z,"--vdbe-trace-off--", 18)==0 ){
   341    342             pParse->db->flags &= ~SQLITE_VdbeTrace;
          343  +#ifdef MEMORY_DEBUG
          344  +        }else if( sqliteStrNICmp(z,"--malloc-file=",14)==0 ){
          345  +          sqlite_iMallocFail = atoi(&z[14]);
          346  +        }else if( sqliteStrNICmp(z,"--malloc-stats--", 16)==0 ){
          347  +          if( pParse->xCallback ){
          348  +            static char *azName[4] = {"malloc", "free", "to_fail", 0 };
          349  +            char *azArg[4];
          350  +            char zVal[3][30];
          351  +            sprintf(zVal[0],"%d", sqlite_nMalloc);
          352  +            sprintf(zVal[1],"%d", sqlite_nFree);
          353  +            sprintf(zVal[2],"%d", sqlite_iMallocFail);
          354  +            azArg[0] = zVal[0];
          355  +            azArg[1] = zVal[1];
          356  +            azArg[2] = zVal[2];
          357  +            azArg[3] = 0;
          358  +            pParse->xCallback(pParse->pArg, 3, azArg, azName);
          359  +          }
          360  +#endif
   342    361           }
          362  +#endif
   343    363           break;
   344    364         }
   345    365         case TK_ILLEGAL:
   346    366           sqliteSetNString(pzErrMsg, "illegal token: \"", -1, 
   347    367              pParse->sLastToken.z, pParse->sLastToken.n, 0);
   348    368           nErr++;
   349    369           break;
   350    370         default:
   351    371           sqliteParser(pEngine, tokenType, pParse->sLastToken, pParse);
   352         -        if( pParse->zErrMsg ){
          372  +        if( pParse->zErrMsg && pParse->sErrToken.z ){
   353    373             sqliteSetNString(pzErrMsg, "near \"", -1, 
   354    374                pParse->sErrToken.z, pParse->sErrToken.n,
   355    375                "\": ", -1,
   356    376                pParse->zErrMsg, -1,
   357    377                0);
   358    378             nErr++;
          379  +          sqliteFree(pParse->zErrMsg);
          380  +          pParse->zErrMsg = 0;
   359    381           }
   360    382           break;
   361    383       }
   362    384     }
   363    385     if( nErr==0 ){
   364    386       sqliteParser(pEngine, 0, pParse->sLastToken, pParse);
   365         -    if( pParse->zErrMsg ){
          387  +    if( pParse->zErrMsg && pParse->sErrToken.z ){
   366    388          sqliteSetNString(pzErrMsg, "near \"", -1, 
   367    389             pParse->sErrToken.z, pParse->sErrToken.n,
   368    390             "\": ", -1,
   369    391             pParse->zErrMsg, -1,
   370    392             0);
   371    393          nErr++;
          394  +       sqliteFree(pParse->zErrMsg);
          395  +       pParse->zErrMsg = 0;
   372    396       }
   373    397     }
   374    398     sqliteParserFree(pEngine, free);
   375    399     if( pParse->zErrMsg ){
   376    400       if( pzErrMsg ){
          401  +      sqliteFree(*pzErrMsg);
   377    402         *pzErrMsg = pParse->zErrMsg;
   378    403       }else{
   379    404         sqliteFree(pParse->zErrMsg);
   380    405       }
   381    406       if( !nErr ) nErr++;
   382    407     }
   383    408     if( pParse->pVdbe ){

Changes to src/util.c.

    22     22   **
    23     23   *************************************************************************
    24     24   ** Utility functions used throughout sqlite.
    25     25   **
    26     26   ** This file contains functions for allocating memory, comparing
    27     27   ** strings, and stuff like that.
    28     28   **
    29         -** $Id: util.c,v 1.11 2000/06/05 16:01:39 drh Exp $
           29  +** $Id: util.c,v 1.12 2000/06/08 13:36:41 drh Exp $
    30     30   */
    31     31   #include "sqliteInt.h"
    32     32   #include <stdarg.h>
    33     33   #include <ctype.h>
    34     34   
    35     35   #ifdef MEMORY_DEBUG
    36     36   
................................................................................
    39     39   ** Allocate new memory and set it to zero.  Return NULL if
    40     40   ** no memory is available.
    41     41   */
    42     42   void *sqliteMalloc_(int n, char *zFile, int line){
    43     43     void *p;
    44     44     int *pi;
    45     45     int k;
           46  +  sqlite_nMalloc++;
           47  +  if( sqlite_iMallocFail>=0 ){
           48  +    sqlite_iMallocFail--;
           49  +    if( sqlite_iMallocFail==0 ) return 0;
           50  +  }
    46     51     k = (n+sizeof(int)-1)/sizeof(int);
    47     52     pi = malloc( (3+k)*sizeof(int));
    48     53     if( pi==0 ) return 0;
    49     54     pi[0] = 0xdead1122;
    50     55     pi[1] = n;
    51     56     pi[k+2] = 0xdead3344;
    52     57     p = &pi[2];
................................................................................
    61     66   ** Free memory previously obtained from sqliteMalloc()
    62     67   */
    63     68   void sqliteFree_(void *p, char *zFile, int line){
    64     69     if( p ){
    65     70       int *pi, k, n;
    66     71       pi = p;
    67     72       pi -= 2;
           73  +    sqlite_nFree++;
    68     74       if( pi[0]!=0xdead1122 ){
    69     75         fprintf(stderr,"Low-end memory corruption at 0x%x\n", (int)p);
    70     76         return;
    71     77       }
    72     78       n = pi[1];
    73     79       k = (n+sizeof(int)-1)/sizeof(int);
    74     80       if( pi[k+2]!=0xdead3344 ){
................................................................................
   119    125     memcpy(p, oldP, n>oldN ? oldN : n);
   120    126     if( n>oldN ){
   121    127       memset(&((char*)p)[oldN], 0, n-oldN);
   122    128     }
   123    129     memset(oldPi, 0, (oldK+3)*sizeof(int));
   124    130     free(oldPi);
   125    131   #if MEMORY_DEBUG>1
   126         -  fprintf(stderr,"realloc %d->%d bytes at 0x%x->0x%x at %s:%d\n", oldN, n,
          132  +  fprintf(stderr,"realloc %d to %d bytes at 0x%x to 0x%x at %s:%d\n", oldN, n,
   127    133       (int)oldP, (int)p, zFile, line);
   128    134   #endif
   129    135     return p;
   130    136   }
   131    137   
   132    138   /*
   133    139   ** Make a duplicate of a string into memory obtained from malloc()
................................................................................
   137    143     char *zNew;
   138    144     if( pz==0 || *pz==0 ) return;
   139    145     zNew = malloc( strlen(*pz) + 1 );
   140    146     if( zNew ) strcpy(zNew, *pz);
   141    147     sqliteFree(*pz);
   142    148     *pz = zNew;
   143    149   }
          150  +
          151  +/*
          152  +** Make a copy of a string in memory obtained from sqliteMalloc()
          153  +*/
          154  +char *sqliteStrDup_(const char *z, char *zFile, int line){
          155  +  char *zNew = sqliteMalloc_(strlen(z)+1, zFile, line);
          156  +  if( zNew ) strcpy(zNew, z);
          157  +  return zNew;
          158  +}
          159  +char *sqliteStrNDup_(const char *z, int n, char *zFile, int line){
          160  +  char *zNew = sqliteMalloc_(n+1, zFile, line);
          161  +  if( zNew ){
          162  +    memcpy(zNew, z, n);
          163  +    zNew[n] = 0;
          164  +  }
          165  +  return zNew;
          166  +}
          167  +
   144    168   
   145    169   #else  /* !defined(MEMORY_DEBUG) */
   146    170   /*
   147    171   ** Allocate new memory and set it to zero.  Return NULL if
   148    172   ** no memory is available.
   149    173   */
   150    174   void *sqliteMalloc(int n){
................................................................................
   174    198     }
   175    199     if( n==0 ){
   176    200       sqliteFree(p);
   177    201       return 0;
   178    202     }
   179    203     return realloc(p, n);
   180    204   }
          205  +
          206  +/*
          207  +** Make a copy of a string in memory obtained from sqliteMalloc()
          208  +*/
          209  +char *sqliteStrDup(const char *z){
          210  +  char *zNew = sqliteMalloc(strlen(z)+1);
          211  +  if( zNew ) strcpy(zNew, z);
          212  +  return zNew;
          213  +}
          214  +char *sqliteStrNDup(const char *z, int n){
          215  +  char *zNew = sqliteMalloc(n+1);
          216  +  if( zNew ){
          217  +    memcpy(zNew, z, n);
          218  +    zNew[n] = 0;
          219  +  }
          220  +  return zNew;
          221  +}
   181    222   #endif /* MEMORY_DEBUG */
   182    223   
   183    224   /*
   184    225   ** Create a string from the 2nd and subsequent arguments (up to the
   185    226   ** first NULL argument), store the string in memory obtained from
   186    227   ** sqliteMalloc() and make the pointer indicated by the 1st argument
   187    228   ** point to that string.
................................................................................
   206    247     zResult += strlen(zResult);
   207    248     va_start(ap, zFirst);
   208    249     while( (z = va_arg(ap, const char*))!=0 ){
   209    250       strcpy(zResult, z);
   210    251       zResult += strlen(zResult);
   211    252     }
   212    253     va_end(ap);
          254  +#ifdef MEMORY_DEBUG
          255  +#if MEMORY_DEBUG>1
          256  +  fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);
          257  +#endif
          258  +#endif
   213    259   }
   214    260   
   215    261   /*
   216    262   ** Works like sqliteSetString, but each string is now followed by
   217    263   ** a length integer.  -1 means use the whole string.
   218    264   */
   219    265   void sqliteSetNString(char **pz, ...){
................................................................................
   239    285     while( (z = va_arg(ap, const char*))!=0 ){
   240    286       n = va_arg(ap, int);
   241    287       if( n<=0 ) n = strlen(z);
   242    288       strncpy(zResult, z, n);
   243    289       zResult += n;
   244    290     }
   245    291     *zResult = 0;
          292  +#ifdef MEMORY_DEBUG
          293  +#if MEMORY_DEBUG>1
          294  +  fprintf(stderr,"string at 0x%x is %s\n", (int)*pz, *pz);
          295  +#endif
          296  +#endif
   246    297     va_end(ap);
   247    298   }
   248    299   
   249    300   /*
   250    301   ** Convert an SQL-style quoted string into a normal string by removing
   251    302   ** the quote characters.  The conversion is done in-place.  If the
   252    303   ** input does not begin with a quote character, then this routine

Changes to src/vdbe.c.

    37     37   ** inplicit conversion from one type to the other occurs as necessary.
    38     38   ** 
    39     39   ** Most of the code in this file is taken up by the sqliteVdbeExec()
    40     40   ** function which does the work of interpreting a VDBE program.
    41     41   ** But other routines are also provided to help in building up
    42     42   ** a program instruction by instruction.
    43     43   **
    44         -** $Id: vdbe.c,v 1.27 2000/06/07 15:39:04 drh Exp $
           44  +** $Id: vdbe.c,v 1.28 2000/06/08 13:36:41 drh Exp $
    45     45   */
    46     46   #include "sqliteInt.h"
    47     47   #include <unistd.h>
    48     48   
    49     49   /*
    50     50   ** SQL is translated into a sequence of instructions to be
    51     51   ** executed by a virtual machine.  Each instruction is an instance
................................................................................
   250    250     p->aOp[i].opcode = op;
   251    251     p->aOp[i].p1 = p1;
   252    252     if( p2<0 && (-1-p2)<p->nLabel && p->aLabel[-1-p2]>=0 ){
   253    253       p2 = p->aLabel[-1-p2];
   254    254     }
   255    255     p->aOp[i].p2 = p2;
   256    256     if( p3 && p3[0] ){
   257         -    sqliteSetString(&p->aOp[i].p3, p3, 0);
          257  +    p->aOp[i].p3 = sqliteStrDup(p3);
   258    258     }else{
   259    259       p->aOp[i].p3 = 0;
   260    260     }
   261    261     if( lbl<0 && (-lbl)<=p->nLabel ){
   262    262       p->aLabel[-1-lbl] = i;
   263    263       for(j=0; j<i; j++){
   264    264         if( p->aOp[j].p2==lbl ) p->aOp[j].p2 = i;
................................................................................
   519    519       sprintf(zBuf,"%d",p->aStack[i].i);
   520    520     }else{
   521    521       p->zStack[i] = "";
   522    522       p->aStack[i].n = 1;
   523    523       p->aStack[i].flags |= STK_Str;
   524    524       return 0;
   525    525     }
   526         -  p->zStack[i] = 0;
   527         -  sqliteSetString(&p->zStack[i], zBuf, 0);
          526  +  p->zStack[i] = sqliteStrDup(zBuf);
   528    527     if( p->zStack[i]==0 ) return 1;
   529    528     p->aStack[i].n = strlen(p->zStack[i])+1;
   530    529     p->aStack[i].flags |= STK_Str|STK_Dyn;
   531    530     return 0;
   532    531   }
   533    532   
   534    533   /*
................................................................................
   842    841       pTail->pNext = pLeft;
   843    842     }else if( pRight ){
   844    843       pTail->pNext = pRight;
   845    844     }
   846    845     return sHead.pNext;
   847    846   }
   848    847   
   849         -
   850    848   /*
   851    849   ** Execute the program in the VDBE.
   852    850   **
   853    851   ** If an error occurs, an error message is written to memory obtained
   854    852   ** from sqliteMalloc() and *pzErrMsg is made to point to that memory.
   855    853   ** The return parameter is the number of errors.
   856    854   **
................................................................................
   882    880     if( access("vdbe_trace",0)==0 ){
   883    881       p->trace = stderr;
   884    882     }
   885    883   #endif
   886    884     /* if( pzErrMsg ){ *pzErrMsg = 0; } */
   887    885     for(pc=0; rc==SQLITE_OK && pc<p->nOp && pc>=0; pc++){
   888    886       pOp = &p->aOp[pc];
          887  +
          888  +    /* Only allow tracing if NDEBUG is not defined.
          889  +    */
          890  +#ifndef NDEBUG
   889    891       if( p->trace ){
   890    892         fprintf(p->trace,"%4d %-12s %4d %4d %s\n",
   891    893           pc, zOpName[pOp->opcode], pOp->p1, pOp->p2,
   892    894              pOp->p3 ? pOp->p3 : "");
   893    895       }
          896  +#endif
          897  +
   894    898       switch( pOp->opcode ){
   895    899         /* Opcode:  Goto P2 * *
   896    900         **
   897    901         ** An unconditional jump to address P2.
   898    902         ** The next instruction executed will be 
   899    903         ** the one at index P2 from the beginning of
   900    904         ** the program.
................................................................................
  1889   1893         ** Turn the key-as-data mode for cursor P1 either on (if P2==1) or
  1890   1894         ** off (if P2==0).  In key-as-data mode, the OP_Fetch opcode pulls
  1891   1895         ** data off of the key rather than the data.  This is useful for
  1892   1896         ** outer joins and stuff...
  1893   1897         */
  1894   1898         case OP_KeyAsData: {
  1895   1899           int i = pOp->p1;
  1896         -        VdbeTable *pTab;
  1897   1900           if( i>=0 && i<p->nTable && p->aTab[i].pTable!=0 ){
  1898   1901             p->aTab[i].keyAsData = pOp->p2;
  1899   1902           }
  1900   1903           break;
  1901   1904         }
  1902   1905   
  1903   1906         /* Opcode: Field P1 P2 *
................................................................................
  2679   2682         ** location P1.  P1 should be a small integer since space is allocated
  2680   2683         ** for all memory locations between 0 and P1 inclusive.
  2681   2684         */
  2682   2685         case OP_MemStore: {
  2683   2686           int i = pOp->p1;
  2684   2687           int tos = p->tos;
  2685   2688           Mem *pMem;
         2689  +        char *zOld;
  2686   2690           if( tos<0 ) goto not_enough_stack;
  2687   2691           if( i>=p->nMem ){
  2688   2692             int nOld = p->nMem;
  2689   2693             p->nMem = i + 5;
  2690   2694             p->aMem = sqliteRealloc(p->aMem, p->nMem*sizeof(p->aMem[0]));
  2691   2695             if( p->aMem==0 ) goto no_mem;
  2692   2696             if( nOld<p->nMem ){
  2693   2697               memset(&p->aMem[nOld], 0, sizeof(p->aMem[0])*(p->nMem-nOld));
  2694   2698             }
  2695   2699           }
  2696   2700           pMem = &p->aMem[i];
  2697   2701           if( pMem->s.flags & STK_Dyn ){
  2698         -          sqliteFree(pMem->z);
         2702  +          zOld = pMem->z;
         2703  +        }else{
         2704  +          zOld = 0;
  2699   2705           }
  2700   2706           pMem->s = p->aStack[tos];
  2701   2707           if( pMem->s.flags & STK_Str ){
  2702         -          pMem->z = 0;
  2703         -          sqliteSetString(&pMem->z, p->zStack[tos], 0);
         2708  +          pMem->z = sqliteStrNDup(p->zStack[tos], pMem->s.n);
  2704   2709             pMem->s.flags |= STK_Dyn;
  2705   2710           }
         2711  +        if( zOld ) sqliteFree(zOld);
  2706   2712           PopStack(p, 1);
  2707   2713           break;
  2708   2714         }
  2709   2715   
  2710   2716         /* Opcode: MemLoad P1 * *
  2711   2717         **
  2712   2718         ** Push a copy of the value in memory location P1 onto the stack.
................................................................................
  2820   2826           AggElem *pFocus = AggInFocus(p->agg);
  2821   2827           int i = pOp->p2;
  2822   2828           int tos = p->tos;
  2823   2829           if( tos<0 ) goto not_enough_stack;
  2824   2830           if( pFocus==0 ) goto no_mem;
  2825   2831           if( i>=0 && i<p->agg.nMem ){
  2826   2832             Mem *pMem = &pFocus->aMem[i];
         2833  +          char *zOld;
         2834  +          if( pMem->s.flags & STK_Dyn ){
         2835  +            zOld = pMem->z;
         2836  +          }else{
         2837  +            zOld = 0;
         2838  +          }
  2827   2839             pMem->s = p->aStack[tos];
  2828   2840             if( pMem->s.flags & STK_Str ){
  2829   2841               pMem->z = sqliteMalloc( p->aStack[tos].n );
  2830   2842               if( pMem->z==0 ) goto no_mem;
  2831   2843               memcpy(pMem->z, p->zStack[tos], pMem->s.n);
  2832   2844               pMem->s.flags |= STK_Str|STK_Dyn;
  2833   2845             }
         2846  +          if( zOld ) sqliteFree(zOld);
  2834   2847           }
  2835   2848           PopStack(p, 1);
  2836   2849           break;
  2837   2850         }
  2838   2851   
  2839   2852         /* Opcode: AggGet * P2 *
  2840   2853         **
................................................................................
  2969   2982         default: {
  2970   2983           sprintf(zBuf,"%d",pOp->opcode);
  2971   2984           sqliteSetString(pzErrMsg, "unknown opcode ", zBuf, 0);
  2972   2985           rc = SQLITE_INTERNAL;
  2973   2986           break;
  2974   2987         }
  2975   2988       }
         2989  +
         2990  +    /* The following code adds nothing to the actual functionality
         2991  +    ** of the program.  It is only here for testing and debugging.
         2992  +    ** On the other hand, it does burn CPU cycles every time through
         2993  +    ** the evaluator loop.  So we can leave it out when NDEBUG is defined.
         2994  +    */
         2995  +#ifndef NDEBUG
  2976   2996       if( pc<-1 || pc>=p->nOp ){
  2977   2997         sqliteSetString(pzErrMsg, "jump destination out of range", 0);
  2978   2998         rc = SQLITE_INTERNAL;
  2979   2999       }
  2980   3000       if( p->trace && p->tos>=0 ){
  2981   3001         int i;
  2982   3002         fprintf(p->trace, "Stack:");
................................................................................
  2995   3015             }
  2996   3016           }else{
  2997   3017             fprintf(p->trace, " ???");
  2998   3018           }
  2999   3019         }
  3000   3020         fprintf(p->trace,"\n");
  3001   3021       }
         3022  +#endif
  3002   3023     }
  3003   3024   
  3004   3025   cleanup:
  3005   3026     Cleanup(p);
  3006   3027     return rc;
  3007   3028   
  3008   3029     /* Jump to here if a malloc() fails.  It's hard to get a malloc()

Changes to test/tester.tcl.

    19     19   #   drh@hwaci.com
    20     20   #   http://www.hwaci.com/drh/
    21     21   #
    22     22   #***********************************************************************
    23     23   # This file implements some common TCL routines used for regression
    24     24   # testing the SQLite library
    25     25   #
    26         -# $Id: tester.tcl,v 1.4 2000/05/31 17:59:27 drh Exp $
           26  +# $Id: tester.tcl,v 1.5 2000/06/08 13:36:41 drh Exp $
    27     27   
    28     28   # Create a test database
    29     29   #
    30     30   file delete -force testdb
    31     31   file mkdir testdb
    32     32   sqlite db testdb
    33     33   
................................................................................
    70     70     }
    71     71   }
    72     72   
    73     73   # Run this routine last
    74     74   #
    75     75   proc finish_test {} {
    76     76     global nTest nErr
           77  +  catch {db close}
    77     78     puts "$nErr errors out of $nTest tests"
    78     79     exit $nErr
    79     80   }
    80     81   
    81     82   # A procedure to execute SQL
    82     83   #
    83     84   proc execsql {sql} {

Added tool/memleak.awk.

            1  +#
            2  +# This script looks for memory leaks by analyzing the output of "sqlite" 
            3  +# when compiled with the MEMORY_DEBUG=2 option.
            4  +#
            5  +/^malloc / {
            6  +  mem[$5] = $0
            7  +}
            8  +/^realloc / {
            9  +  mem[$7] = "";
           10  +  mem[$9] = $0
           11  +}
           12  +/^free / {
           13  +  mem[$5] = "";
           14  +}
           15  +/^string at / {
           16  +  addr = $3
           17  +  sub("string at " addr " is ","")
           18  +  str[addr] = $0
           19  +}
           20  +END {
           21  +  for(addr in mem){
           22  +    if( mem[addr]=="" ) continue
           23  +    print mem[addr], str[addr]
           24  +  }
           25  +}