/ Check-in [ef0250f3]
Login

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

Overview
Comment:Add the capability to track the maximum depth of the LALR(1) parser stack so that critical applications can check to see if they are getting close to limits. (CVS 5481)
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:ef0250f3dc769a4acd534f31fa06d90922d4145b
User & Date: drh 2008-07-25 15:39:04
Context
2008-07-25
16:07
Further performance improvements to mem6.c. (CVS 5482) check-in: 4528f7b1 user: danielk1977 tags: trunk
15:39
Add the capability to track the maximum depth of the LALR(1) parser stack so that critical applications can check to see if they are getting close to limits. (CVS 5481) check-in: ef0250f3 user: drh tags: trunk
14:53
Fix the corrupt7 tests to track changes in the integrity check error message. (CVS 5480) check-in: 22177dac user: drh tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/sqlite.h.in.

    26     26   ** on how SQLite interfaces are suppose to operate.
    27     27   **
    28     28   ** The name of this file under configuration management is "sqlite.h.in".
    29     29   ** The makefile makes some minor changes to this file (such as inserting
    30     30   ** the version number) and changes its name to "sqlite3.h" as
    31     31   ** part of the build process.
    32     32   **
    33         -** @(#) $Id: sqlite.h.in,v 1.379 2008/07/25 08:49:00 danielk1977 Exp $
           33  +** @(#) $Id: sqlite.h.in,v 1.380 2008/07/25 15:39:04 drh Exp $
    34     34   */
    35     35   #ifndef _SQLITE3_H_
    36     36   #define _SQLITE3_H_
    37     37   #include <stdarg.h>     /* Needed for the definition of va_list */
    38     38   
    39     39   /*
    40     40   ** Make sure we can call this stuff from C++.
................................................................................
  6115   6115   **
  6116   6116   ** <dt>SQLITE_STATUS_MALLOC_SIZE</dt>
  6117   6117   ** <dd>This parameter records the largest memory allocation request
  6118   6118   ** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their
  6119   6119   ** internal equivalents).  The value of interest is return in the
  6120   6120   ** *pHighwater parameter to [sqlite3_status()].  The value written
  6121   6121   ** into the *pCurrent parameter is undefined.</dd>
         6122  +**
         6123  +** <dt>SQLITE_STATUS_PARSER_STACK</dt>
         6124  +** <dd>This parameter records the deepest parser stack.  It is only
         6125  +** meaningful if SQLite is compiled with YYTRACKMAXSTACKDEPTH.</dd>
  6122   6126   ** </dl>
  6123   6127   **
  6124   6128   ** New status parameters may be added from time to time.
  6125   6129   */
  6126   6130   #define SQLITE_STATUS_MEMORY_USED          0
  6127   6131   #define SQLITE_STATUS_PAGECACHE_USED       1
  6128   6132   #define SQLITE_STATUS_PAGECACHE_OVERFLOW   2
  6129   6133   #define SQLITE_STATUS_SCRATCH_USED         3
  6130   6134   #define SQLITE_STATUS_SCRATCH_OVERFLOW     4
  6131   6135   #define SQLITE_STATUS_MALLOC_SIZE          5
         6136  +#define SQLITE_STATUS_PARSER_STACK         6
  6132   6137   
  6133   6138   
  6134   6139   /*
  6135   6140   ** Undo the hack that converts floating point types to integer for
  6136   6141   ** builds on processors without floating point support.
  6137   6142   */
  6138   6143   #ifdef SQLITE_OMIT_FLOATING_POINT

Changes to src/sqliteInt.h.

     7      7   **    May you do good and not evil.
     8      8   **    May you find forgiveness for yourself and forgive others.
     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   ** Internal interface definitions for SQLite.
    13     13   **
    14         -** @(#) $Id: sqliteInt.h,v 1.745 2008/07/25 08:49:00 danielk1977 Exp $
           14  +** @(#) $Id: sqliteInt.h,v 1.746 2008/07/25 15:39:04 drh Exp $
    15     15   */
    16     16   #ifndef _SQLITEINT_H_
    17     17   #define _SQLITEINT_H_
    18     18   
    19     19   /*
    20     20   ** Include the configuration header output by 'configure' if we're using the
    21     21   ** autoconf-based build
................................................................................
  1786   1786     void *pPage;                      /* Page cache memory */
  1787   1787     int szPage;                       /* Size of each page in pPage[] */
  1788   1788     int nPage;                        /* Number of pages in pPage[] */
  1789   1789     int isInit;                       /* True after initialization has finished */
  1790   1790     int isMallocInit;                 /* True after malloc is initialized */
  1791   1791     sqlite3_mutex *pInitMutex;        /* Mutex used by sqlite3_initialize() */
  1792   1792     int nSmall;                       /* alloc size threshold used by mem6.c */
         1793  +  int mxParserStack;                /* maximum depth of the parser stack */
  1793   1794   };
  1794   1795   
  1795   1796   /*
  1796   1797   ** Assuming zIn points to the first byte of a UTF-8 character,
  1797   1798   ** advance zIn to point to the first byte of the next UTF-8 character.
  1798   1799   */
  1799   1800   #define SQLITE_SKIP_UTF8(zIn) {                        \
................................................................................
  2191   2192   
  2192   2193   /*
  2193   2194   ** The interface to the LEMON-generated parser
  2194   2195   */
  2195   2196   void *sqlite3ParserAlloc(void*(*)(size_t));
  2196   2197   void sqlite3ParserFree(void*, void(*)(void*));
  2197   2198   void sqlite3Parser(void*, int, Token, Parse*);
         2199  +#ifdef YYTRACKMAXSTACKDEPTH
         2200  +  int sqlite3ParserStackPeak(void*);
         2201  +#endif
  2198   2202   
  2199   2203   int sqlite3AutoLoadExtensions(sqlite3*);
  2200   2204   #ifndef SQLITE_OMIT_LOAD_EXTENSION
  2201   2205     void sqlite3CloseExtensions(sqlite3*);
  2202   2206   #else
  2203   2207   # define sqlite3CloseExtensions(X)
  2204   2208   #endif

Changes to src/status.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   **
    13     13   ** This module implements the sqlite3_status() interface and related
    14     14   ** functionality.
    15     15   **
    16         -** $Id: status.c,v 1.3 2008/07/11 16:15:18 drh Exp $
           16  +** $Id: status.c,v 1.4 2008/07/25 15:39:04 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   
    20     20   /*
    21     21   ** Variables in which to record status information.
    22     22   */
    23     23   static struct {
    24         -  int nowValue[6];         /* Current value */
    25         -  int mxValue[6];          /* Maximum value */
           24  +  int nowValue[7];         /* Current value */
           25  +  int mxValue[7];          /* Maximum value */
    26     26   } sqlite3Stat;
    27     27   
    28     28   
    29     29   /*
    30     30   ** Reset the status records.  This routine is called by
    31     31   ** sqlite3_initialize().
    32     32   */

Changes to src/test_config.c.

    12     12   ** 
    13     13   ** This file contains code used for testing the SQLite system.
    14     14   ** None of the code in this file goes into a deliverable build.
    15     15   ** 
    16     16   ** The focus of this file is providing the TCL testing layer
    17     17   ** access to compile-time constants.
    18     18   **
    19         -** $Id: test_config.c,v 1.31 2008/07/08 23:40:20 drh Exp $
           19  +** $Id: test_config.c,v 1.32 2008/07/25 15:39:04 drh Exp $
    20     20   */
    21     21   
    22     22   #include "sqliteLimit.h"
    23     23   
    24     24   #include "sqliteInt.h"
    25     25   #include "tcl.h"
    26     26   #include <stdlib.h>
................................................................................
   432    432   #endif
   433    433   
   434    434   #ifdef SQLITE_SECURE_DELETE
   435    435     Tcl_SetVar2(interp, "sqlite_options", "secure_delete", "1", TCL_GLOBAL_ONLY);
   436    436   #else
   437    437     Tcl_SetVar2(interp, "sqlite_options", "secure_delete", "0", TCL_GLOBAL_ONLY);
   438    438   #endif
          439  +
          440  +#ifdef YYTRACKMAXSTACKDEPTH
          441  +  Tcl_SetVar2(interp, "sqlite_options", "yytrackmaxstackdepth", "1", TCL_GLOBAL_ONLY);
          442  +#else
          443  +  Tcl_SetVar2(interp, "sqlite_options", "yytrackmaxstackdepth", "0", TCL_GLOBAL_ONLY);
          444  +#endif
   439    445   
   440    446   #define LINKVAR(x) { \
   441    447       static const int cv_ ## x = SQLITE_ ## x; \
   442    448       Tcl_LinkVar(interp, "SQLITE_" #x, (char *)&(cv_ ## x), \
   443    449                   TCL_LINK_INT | TCL_LINK_READ_ONLY); }
   444    450   
   445    451     LINKVAR( MAX_LENGTH );

Changes to src/test_malloc.c.

     9      9   **    May you share freely, never taking more than you give.
    10     10   **
    11     11   *************************************************************************
    12     12   **
    13     13   ** This file contains code used to implement test interfaces to the
    14     14   ** memory allocation subsystem.
    15     15   **
    16         -** $Id: test_malloc.c,v 1.40 2008/07/25 08:49:00 danielk1977 Exp $
           16  +** $Id: test_malloc.c,v 1.41 2008/07/25 15:39:04 drh Exp $
    17     17   */
    18     18   #include "sqliteInt.h"
    19     19   #include "tcl.h"
    20     20   #include <stdlib.h>
    21     21   #include <string.h>
    22     22   #include <assert.h>
    23     23   
................................................................................
  1079   1079     } aOp[] = {
  1080   1080       { "SQLITE_STATUS_MEMORY_USED",         SQLITE_STATUS_MEMORY_USED         },
  1081   1081       { "SQLITE_STATUS_PAGECACHE_USED",      SQLITE_STATUS_PAGECACHE_USED      },
  1082   1082       { "SQLITE_STATUS_PAGECACHE_OVERFLOW",  SQLITE_STATUS_PAGECACHE_OVERFLOW  },
  1083   1083       { "SQLITE_STATUS_SCRATCH_USED",        SQLITE_STATUS_SCRATCH_USED        },
  1084   1084       { "SQLITE_STATUS_SCRATCH_OVERFLOW",    SQLITE_STATUS_SCRATCH_OVERFLOW    },
  1085   1085       { "SQLITE_STATUS_MALLOC_SIZE",         SQLITE_STATUS_MALLOC_SIZE         },
         1086  +    { "SQLITE_STATUS_PARSER_STACK",        SQLITE_STATUS_PARSER_STACK        },
  1086   1087     };
  1087   1088     Tcl_Obj *pResult;
  1088   1089     if( objc!=3 ){
  1089   1090       Tcl_WrongNumArgs(interp, 1, objv, "PARAMETER RESETFLAG");
  1090   1091       return TCL_ERROR;
  1091   1092     }
  1092   1093     zOpName = Tcl_GetString(objv[1]);

Changes to src/tokenize.c.

    11     11   *************************************************************************
    12     12   ** An tokenizer for SQL
    13     13   **
    14     14   ** This file contains C code that splits an SQL input string up into
    15     15   ** individual tokens and sends those tokens one-by-one over to the
    16     16   ** parser for analysis.
    17     17   **
    18         -** $Id: tokenize.c,v 1.146 2008/07/08 19:34:07 drh Exp $
           18  +** $Id: tokenize.c,v 1.147 2008/07/25 15:39:04 drh Exp $
    19     19   */
    20     20   #include "sqliteInt.h"
    21     21   #include <ctype.h>
    22     22   #include <stdlib.h>
    23     23   
    24     24   /*
    25     25   ** The charMap() macro maps alphabetic characters into their
................................................................................
   451    451     if( zSql[i]==0 && nErr==0 && pParse->rc==SQLITE_OK ){
   452    452       if( lastTokenParsed!=TK_SEMI ){
   453    453         sqlite3Parser(pEngine, TK_SEMI, pParse->sLastToken, pParse);
   454    454         pParse->zTail = &zSql[i];
   455    455       }
   456    456       sqlite3Parser(pEngine, 0, pParse->sLastToken, pParse);
   457    457     }
          458  +#ifdef YYTRACKMAXSTACKDEPTH
          459  +  sqlite3StatusSet(SQLITE_STATUS_PARSER_STACK,
          460  +      sqlite3ParserStackPeak(pEngine)
          461  +  );
          462  +#endif /* YYDEBUG */
   458    463     sqlite3ParserFree(pEngine, sqlite3_free);
   459    464     if( db->mallocFailed ){
   460    465       pParse->rc = SQLITE_NOMEM;
   461    466     }
   462    467     if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
   463    468       sqlite3SetString(&pParse->zErrMsg, db, "%s", sqlite3ErrStr(pParse->rc));
   464    469     }

Changes to test/tester.tcl.

     7      7   #    May you find forgiveness for yourself and forgive others.
     8      8   #    May you share freely, never taking more than you give.
     9      9   #
    10     10   #***********************************************************************
    11     11   # This file implements some common TCL routines used for regression
    12     12   # testing the SQLite library
    13     13   #
    14         -# $Id: tester.tcl,v 1.132 2008/07/12 15:55:55 danielk1977 Exp $
           14  +# $Id: tester.tcl,v 1.133 2008/07/25 15:39:04 drh Exp $
    15     15   
    16     16   #
    17     17   # What for user input before continuing.  This gives an opportunity
    18     18   # to connect profiling tools to the process.
    19     19   #
    20     20   for {set i 0} {$i<[llength $argv]} {incr i} {
    21     21     if {[regexp {^-+pause$} [lindex $argv $i] all value]} {
................................................................................
   378    378     puts "Page-cache overflow:  $val"
   379    379     set x [sqlite3_status SQLITE_STATUS_SCRATCH_USED 0]
   380    380     set val [format {now %10d  max %10d} [lindex $x 1] [lindex $x 2]]
   381    381     puts "Scratch memory used:  $val"
   382    382     set x [sqlite3_status SQLITE_STATUS_SCRATCH_OVERFLOW 0]
   383    383     set val [format {now %10d  max %10d} [lindex $x 1] [lindex $x 2]]
   384    384     puts "Scratch overflow:     $val"
          385  +  ifcapable yytrackmaxstackdepth {
          386  +    set x [sqlite3_status SQLITE_STATUS_PARSER_STACK 0]
          387  +    set val [format {               max %10d} [lindex $x 2]]
          388  +    puts "Parser stack depth:    $val"
          389  +  }
   385    390     set x [sqlite3_status SQLITE_STATUS_MALLOC_SIZE 0]
   386    391     puts "Maximum alloc size:   [lindex $x 2]"
   387    392   }
   388    393   
   389    394   # A procedure to execute SQL
   390    395   #
   391    396   proc execsql {sql {db db}} {

Changes to tool/lempar.c.

   151    151   };
   152    152   typedef struct yyStackEntry yyStackEntry;
   153    153   
   154    154   /* The state of the parser is completely contained in an instance of
   155    155   ** the following structure */
   156    156   struct yyParser {
   157    157     int yyidx;                    /* Index of top element in stack */
          158  +#ifdef YYTRACKMAXSTACKDEPTH
          159  +  int yyidxMax;                 /* Maximum value of yyidx */
          160  +#endif
   158    161     int yyerrcnt;                 /* Shifts left before out of the error */
   159    162     ParseARG_SDECL                /* A place to hold %extra_argument */
   160    163   #if YYSTACKDEPTH<=0
   161    164     int yystksz;                  /* Current side of the stack */
   162    165     yyStackEntry *yystack;        /* The parser's stack */
   163    166   #else
   164    167     yyStackEntry yystack[YYSTACKDEPTH];  /* The parser's stack */
................................................................................
   251    254   ** to Parse and ParseFree.
   252    255   */
   253    256   void *ParseAlloc(void *(*mallocProc)(size_t)){
   254    257     yyParser *pParser;
   255    258     pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
   256    259     if( pParser ){
   257    260       pParser->yyidx = -1;
          261  +#ifdef YYTRACKMAXSTACKDEPTH
          262  +    pParser->yyidxMax = 0;
          263  +#endif
   258    264   #if YYSTACKDEPTH<=0
   259    265       yyGrowStack(pParser);
   260    266   #endif
   261    267     }
   262    268     return pParser;
   263    269   }
   264    270   
................................................................................
   331    337     while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
   332    338   #if YYSTACKDEPTH<=0
   333    339     free(pParser->yystack);
   334    340   #endif
   335    341     (*freeProc)((void*)pParser);
   336    342   }
   337    343   
          344  +/*
          345  +** Return the peak depth of the stack for a parser.
          346  +*/
          347  +#ifdef YYTRACKMAXSTACKDEPTH
          348  +int ParseStackPeak(void *p){
          349  +  yyParser *pParser = (yyParser*)p;
          350  +  return pParser->yyidxMax;
          351  +}
          352  +#endif
          353  +
   338    354   /*
   339    355   ** Find the appropriate action for a parser given the terminal
   340    356   ** look-ahead token iLookAhead.
   341    357   **
   342    358   ** If the look-ahead token is YYNOCODE, then check to see if the action is
   343    359   ** independent of the look-ahead.  If it is, return the action, otherwise
   344    360   ** return YY_NO_ACTION.
................................................................................
   451    467     yyParser *yypParser,          /* The parser to be shifted */
   452    468     int yyNewState,               /* The new state to shift in */
   453    469     int yyMajor,                  /* The major token to shift in */
   454    470     YYMINORTYPE *yypMinor         /* Pointer to the minor token to shift in */
   455    471   ){
   456    472     yyStackEntry *yytos;
   457    473     yypParser->yyidx++;
          474  +#ifdef YYTRACKMAXSTACKDEPTH
          475  +  if( yypParser->yyidx>yypParser->yyidxMax ){
          476  +    yypParser->yyidxMax = yypParser->yyidx;
          477  +  }
          478  +#endif
   458    479   #if YYSTACKDEPTH>0 
   459    480     if( yypParser->yyidx>=YYSTACKDEPTH ){
   460    481       yyStackOverflow(yypParser, yypMinor);
   461    482       return;
   462    483     }
   463    484   #else
   464    485     if( yypParser->yyidx>=yypParser->yystksz ){