Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | In fuzzershell: (1) comment fixes. (2) Set and clear g.zTestName[] correctly. (3) Use the value in g.zTestName[] in error messages. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
b7394755fab81329d56bad1b506e536b |
User & Date: | drh 2015-04-25 11:35:48.066 |
Context
2015-04-25
| ||
12:20 | Fix an obscure memory leak that could follow an OOM in where.c. (check-in: 08ec9f2f5a user: dan tags: trunk) | |
11:35 | In fuzzershell: (1) comment fixes. (2) Set and clear g.zTestName[] correctly. (3) Use the value in g.zTestName[] in error messages. (check-in: b7394755fa user: drh tags: trunk) | |
11:19 | In the fuzzershell, always invoke the trace and log callbacks even if output is suppressed. Keep track of the current test name in a global variable for simplified debugging. (check-in: 3045f45481 user: drh tags: trunk) | |
Changes
Changes to tool/fuzzershell.c.
︙ | ︙ | |||
28 29 30 31 32 33 34 | ** (3) The main in-memory database can be initialized from a template ** disk database so that the fuzzer starts with a database containing ** content. ** ** (4) The eval() SQL function is added, allowing the fuzzer to do ** interesting recursive operations. ** | > > | | | | | | | 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 | ** (3) The main in-memory database can be initialized from a template ** disk database so that the fuzzer starts with a database containing ** content. ** ** (4) The eval() SQL function is added, allowing the fuzzer to do ** interesting recursive operations. ** ** (5) An error is raised if there is a memory leak. ** ** The input text can be divided into separate test cases using comments ** of the form: ** ** |****<...>****| ** ** where the "..." is arbitrary text, except the "|" should really be "/". ** ("|" is used here to avoid compiler errors about nested comments.) ** A separate in-memory SQLite database is created to run each test case. ** This feature allows the "queue" of AFL to be captured into a single big ** file using a command like this: ** ** (for i in id:*; do echo '|****<'$i'>****|'; cat $i; done) >~/all-queue.txt ** ** (Once again, change the "|" to "/") Then all elements of the AFL queue ** can be run in a single go (for regression testing, for example) by typing: ** ** fuzzershell -f ~/all-queue.txt ** ** After running each chunk of SQL, the database connection is closed. The ** program aborts if the close fails or if there is any unfreed memory after ** the close. ** ** New test cases can be appended to all-queue.txt at any time. If redundant ** test cases are added, they can be eliminated by running: ** ** fuzzershell -f ~/all-queue.txt --unique-cases ~/unique-cases.txt ** */ #include <stdio.h> #include <stdlib.h> #include <string.h> |
︙ | ︙ | |||
83 84 85 86 87 88 89 | } g; /* ** This routine is called when a simulated OOM occurs. It exists as a ** convenient place to set a debugger breakpoint. */ static void oomFault(void){ | | | 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | } g; /* ** This routine is called when a simulated OOM occurs. It exists as a ** convenient place to set a debugger breakpoint. */ static void oomFault(void){ g.nOomBrkpt++; /* Prevent oomFault() from being optimized out */ } /* Versions of malloc() and realloc() that simulate OOM conditions */ static void *oomMalloc(int nByte){ if( nByte>0 && g.bOomEnable && g.iOomCntdown>0 ){ g.iOomCntdown--; |
︙ | ︙ | |||
119 120 121 122 123 124 125 | /* ** Print an error message and abort in such a way to indicate to the ** fuzzer that this counts as a crash. */ static void abendError(const char *zFormat, ...){ va_list ap; | > > > | > > > > | > | 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | /* ** Print an error message and abort in such a way to indicate to the ** fuzzer that this counts as a crash. */ static void abendError(const char *zFormat, ...){ va_list ap; if( g.zTestName[0] ){ fprintf(stderr, "%s (%s): ", g.zArgv0, g.zTestName); }else{ fprintf(stderr, "%s: ", g.zArgv0); } va_start(ap, zFormat); vfprintf(stderr, zFormat, ap); va_end(ap); fprintf(stderr, "\n"); abort(); } /* ** Print an error message and quit, but not in a way that would look ** like a crash. */ static void fatalError(const char *zFormat, ...){ va_list ap; if( g.zTestName[0] ){ fprintf(stderr, "%s (%s): ", g.zArgv0, g.zTestName); }else{ fprintf(stderr, "%s: ", g.zArgv0); } va_start(ap, zFormat); vfprintf(stderr, zFormat, ap); va_end(ap); fprintf(stderr, "\n"); exit(1); } |
︙ | ︙ | |||
594 595 596 597 598 599 600 | } } for(i=0; i<nIn; i=iNext+1){ /* Skip initial lines beginning with '#' */ if( zIn[i]!='#' ) break; for(iNext=i+1; iNext<nIn && zIn[iNext]!='\n'; iNext++){} } nHeader = i; | | | | 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 | } } for(i=0; i<nIn; i=iNext+1){ /* Skip initial lines beginning with '#' */ if( zIn[i]!='#' ) break; for(iNext=i+1; iNext<nIn && zIn[iNext]!='\n'; iNext++){} } nHeader = i; for(nTest=0; i<nIn; i=iNext, nTest++, g.zTestName[0]=0){ char cSaved; if( strncmp(&zIn[i], "/****<",6)==0 ){ char *z = strstr(&zIn[i], ">****/"); if( z ){ z += 6; sqlite3_snprintf(sizeof(g.zTestName), g.zTestName, "%.*s", (int)(z-&zIn[i]), &zIn[i]); if( verboseFlag ){ printf("%.*s\n", (int)(z-&zIn[i]), &zIn[i]); fflush(stdout); } i += (int)(z-&zIn[i]); multiTest = 1; |
︙ | ︙ |