SQLite Forum

Another CLI crashing problem

Another CLI crashing problem

(1) By Yu Liang (LY1598773890) on 2022-10-30 22:56:48 [source]

The SQLite3 CLI tool crashes when executing the following query:

PRAGMA hard_heap_limit=1

We tested SQLite3 on version: 7660db2a2e and observed the crash.

The stack trace for the crash is shown below:

#0  0x000000000043ab78 in shell_error_context (zSql=0x6afef0 "PRAGMA hard_heap_limit=1\n0", db=0x6a8a20) at shell.c:17008
#1  0x000000000043ebaf in save_err_msg (db=0x6a8a20, zPhase=0x61bd17 "in prepare", rc=0x1, zSql=0x6afef0 "PRAGMA hard_heap_limit=1\n0") at shell.c:17088
#2  0x0000000000418e21 in shell_exec (pArg=0x7fffffffc7c0, zSql=0x6afef0 "PRAGMA hard_heap_limit=1\n0", pzErrMsg=0x7fffffffc5b0) at shell.c:18236
#3  0x00000000004435ef in runOneSqlLine (p=0x7fffffffc7c0, zSql=0x6afef0 "PRAGMA hard_heap_limit=1\n0", in=0x7ffff7d6d980 <_IO_2_1_stdin_>, startline=0x1)
    at shell.c:25330
#4  0x0000000000419ffa in process_input (p=0x7fffffffc7c0) at shell.c:25513
#5  0x000000000040b9b7 in main (argc=0x1, argv=0x7fffffffdde8) at shell.c:26349
#6  0x00007ffff7ba5083 in __libc_start_main (main=0x409a90 <main>, argc=0x1, argv=0x7fffffffdde8, init=<optimized out>, fini=<optimized out>, rtld_fini=<optimized out>,
    stack_end=0x7fffffffddd8) at ../csu/libc-start.c:308
#7  0x000000000040377e in _start ()

And when using the UBSAN, the sanitizer outputs the following error information:

shell.c:17008:12: runtime error: applying zero offset to null pointer
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior shell.c:17008:12 in
shell.c:17008:12: runtime error: load of null pointer of type 'char'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior shell.c:17008:12 in
==3202882==ERROR: UndefinedBehaviorSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000558dac bp 0x7fff888d9c00 sp 0x7fff888d9aa0 T3202882)
==3202882==The signal is caused by a READ memory access.
==3202882==Hint: address points to the zero page.
    #0 0x558dac in shell_error_context (/home/luy70/Desktop/sqlite_source_fossil/sqlite/sqlite3+0x558dac)
    #1 0x56db6e in save_err_msg (/home/luy70/Desktop/sqlite_source_fossil/sqlite/sqlite3+0x56db6e)
    #2 0x47e763 in shell_exec (/home/luy70/Desktop/sqlite_source_fossil/sqlite/sqlite3+0x47e763)
    #3 0x583e77 in runOneSqlLine (/home/luy70/Desktop/sqlite_source_fossil/sqlite/sqlite3+0x583e77)
    #4 0x482e03 in process_input (/home/luy70/Desktop/sqlite_source_fossil/sqlite/sqlite3+0x482e03)
    #5 0x4425a3 in main (/home/luy70/Desktop/sqlite_source_fossil/sqlite/sqlite3+0x4425a3)
    #6 0x7f94b6d24082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16
    #7 0x40597d in _start (/home/luy70/Desktop/sqlite_source_fossil/sqlite/sqlite3+0x40597d)

UndefinedBehaviorSanitizer can not provide additional info.
SUMMARY: UndefinedBehaviorSanitizer: SEGV (/home/luy70/Desktop/sqlite_source_fossil/sqlite/sqlite3+0x558dac) in shell_error_context

Additionally, we run bisecting on the SQLite3 history versions. The bug seems to be introduced in commit 416602a851.

bisect complete
  1 BAD     2022-10-30 11:39:47 7660db2a2e9c4f3a
  2 BAD     2022-06-22 18:33:21 5247df05991df979
  6 BAD     2022-01-12 20:31:14 9282bcde301cee2a
 10 BAD     2021-12-31 18:26:50 a9bfb621091b6d92
 12 BAD     2021-12-29 13:32:36 d4870c08893ea998
 14 BAD     2021-12-29 04:13:37 416602a85101c2cd
 15 GOOD    2021-12-29 04:10:49 155c3e9c7ccd6fd6 CURRENT
 13 GOOD    2021-12-29 04:10:03 e773d6219bded9a5
 11 GOOD    2021-12-21 16:59:45 7b4f9d95a95f685e
  9 GOOD    2021-12-14 20:13:28 5c3d398d20b86a15
  8 GOOD    2021-11-19 19:11:58 d814ba6effc7c5b0
  7 GOOD    2021-10-08 18:15:50 b8c9a54664a87ac4
  5 GOOD    2021-06-22 14:59:34 53f64e83b39cb56a
  4 GOOD    2020-04-04 11:58:22 921448f0e24a3753
  3 GOOD    2018-05-14 00:41:12 d0f35739af3b226c

Thank you. Please let us know if you need further debug information.

(2.1) By jose isaias cabrera (jicman) on 2022-10-31 12:57:33 edited from 2.0 in reply to 1 [link] [source]

In Windows it gives 'Error: out of memory' and aborts with just 'PRAGMA hard_heap_limit=1;'

-- Loading resources from C:\Users\jicman/.sqliterc
SQLite version 3.39.4 2022-09-29 15:55:41
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> PRAGMA hard_heap_limit=1;
Error: out of memory



(3) By Trudge on 2022-10-31 17:42:15 in reply to 2.1 [link] [source]

I had the same result on macOS Monterey on an M1:

2022-10-31 13:39:46
~/MyDB trudge: sqlite
-- Loading resources from /Users/trudge/.sqliterc
SQLite version 3.38.2 2022-03-26 13:51:10
Enter ".help" for usage hints.
Connected to a transient in-memory database.
Use ".open FILENAME" to reopen on a persistent database.
sqlite> PRAGMA hard_heap_limit=1;
Error: out of memory
2022-10-31 13:40:18
~/MyDB trudge: 

(4) By anonymous on 2022-10-31 18:34:20 in reply to 2.1 [link] [source]

FWIW the sqlite online wasm fiddle has similar characteristics when executing:

PRAGMA hard_heap_limit=1;

(5) By Richard Hipp (drh) on 2022-10-31 18:48:50 in reply to 4 [link] [source]

"Similar" in the sense that you cannot recreate the behavior observed by Yu Liang? Nor has anybody else. But I did check-in a change (cb12ac5de17e677f) that should address the issue, if his stack trace is correct.

(6) By jose isaias cabrera (jicman) on 2022-10-31 19:27:40 in reply to 5 [link] [source]

This is fiddle's result:

SQLite version 3.40.0 2022-10-26 15:40:17
Welcome to the "fiddle" shell.

Enter ".help" for usage hints.
.nullvalue NULL
.headers on
Resetting database.
Error: out of memory
FATAL ERROR: Program terminated with exit(1)
Restarting the app requires reloading the page.

And on the top of the screen one gets,

Exception thrown, see JavaScript console: [object Object]

I hope this helps.


(7) By Richard Hipp (drh) on 2022-10-31 20:22:35 in reply to 6 [link] [source]

Yes. When an out-of-memory (OOM) error is seen, the usual behavior of the CLI is to invoke exit(). That is what you are seeing here. The bug report from Yu Liang is that instead of calling exit(), the code is trying to dereference a NULL pointer. That is a very different matter. I have not seen any reproduction of the code dereferencing a NULL pointer. Nevertheless, the CLI source code has been updated to guard against this, based on the stack trace provided by Yu Liang.

(8.1) By Yu Liang (LY1598773890) on 2022-10-31 20:43:12 edited from 8.0 in reply to 7 [link] [source]

Hi Richard, after applying patch d6893183, the NULL pointer dereference problem is also gone on our side. We believe the bug is fixed.

Some additional debug information when triggering the crash in version: 7660db2a2e: We are using x86-64 Ubuntu 20.04 LTS operating system. And the compiler we used is gcc-9 (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0. The configure command we used is shown below:

CC=gcc-9 ./configure --enable-debug

And the command we used to crash the application is:

./sqlite3 < poc

where the poc file holds the PoC query:

PRAGMA hard_heap_limit=1

Here is the full backtrace from gdb:

#0  0x000055555558afa1 in shell_error_context (zSql=0x555555794ef0 "PRAGMA hard_heap_limit=1\n0", db=0x55555578da20) at shell.c:17008
        iOffset = 0x19
        len = 0x1a
        zCode = 0x0
        zMsg = 0x7fffffffc4d0 "P\305\377\377\377\177"
        i = 0x0
#1  0x000055555558b322 in save_err_msg (db=0x55555578da20, zPhase=0x5555557130fd "in prepare", rc=0x1, zSql=0x555555794ef0 "PRAGMA hard_heap_limit=1\n0") at shell.c:17088
        zErr = 0x155586759 <error: Cannot access memory at address 0x155586759>
        zContext = 0x0
        pStr = 0x555555785260 <sqlite3OomStr>
#2  0x000055555558f079 in shell_exec (pArg=0x7fffffffceb0, zSql=0x555555794ef0 "PRAGMA hard_heap_limit=1\n0", pzErrMsg=0x7fffffffc588) at shell.c:18236
        zStmtSql = 0x0
        pStmt = 0x0
        rc = 0x1
        rc2 = 0x0
        zLeftover = 0x555555794f0a ""
        db = 0x55555578da20
#3  0x00005555555a3012 in runOneSqlLine (p=0x7fffffffceb0, zSql=0x555555794ef0 "PRAGMA hard_heap_limit=1\n0", in=0x7ffff7dc8980 <_IO_2_1_stdin_>, startline=0x1)
    at shell.c:25330
        rc = 0x5555
        zErrMsg = 0x0
#4  0x00005555555a37e4 in process_input (p=0x7fffffffceb0) at shell.c:25513
        zLine = 0x0
        zSql = 0x555555794ef0 "PRAGMA hard_heap_limit=1\n0"
        nLine = 0x1
        nSql = 0x1a
        nAlloc = 0x7c
        rc = 0x0
        errCnt = 0x0
        startline = 0x1
        qss = QSS_HasDark
        __PRETTY_FUNCTION__ = "process_input"
#5  0x00005555555a5914 in main (argc=0x1, argv=0x7fffffffe228) at shell.c:26349
        mem_main_enter = 0x0
        zErrMsg = 0x0
        data = {
          db = 0x55555578da20,
          autoExplain = 0x1,
          autoEQP = 0x0,
          autoEQPtest = 0x0,
          autoEQPtrace = 0x0,
          scanstatsOn = 0x0,
          openMode = 0x1,
          doXdgOpen = 0x0,
          nEqpLevel = 0x0,
          eTraceType = 0x0,
          bSafeMode = 0x0,
          bSafeModePersist = 0x0,
          cmOpts = {
            iWrap = 0x0,
            bQuote = 0x0,
            bWordWrap = 0x0
          statsOn = 0x0,
          mEqpLines = 0x0,
          inputNesting = 0x1,
          outCount = 0x0,
          cnt = 0x0,
          lineno = 0x2,
          openFlags = 0x0,
          in = 0x7ffff7dc8980 <_IO_2_1_stdin_>,
          out = 0x7ffff7dc96a0 <_IO_2_1_stdout_>,
          traceOut = 0x0,
          nErr = 0x0,
          mode = 0x2,
          modePrior = 0x0,
          cMode = 0x2,
          normalMode = 0x2,
          writableSchema = 0x0,
          showHeader = 0x0,
          nCheck = 0x0,
          nProgress = 0x0,
          mxProgress = 0x0,
          flgProgress = 0x0,
          shellFlgs = 0x2,
          priorShFlgs = 0x0,
          szMax = 0x0,
          zDestTable = 0x0,
          zTempFile = 0x0,
          zTestcase = '\000' <repeats 29 times>,
          colSeparator = "|", '\000' <repeats 18 times>,
          rowSeparator = "\n", '\000' <repeats 18 times>,
          colSepPrior = '\000' <repeats 19 times>,
          rowSepPrior = '\000' <repeats 19 times>,
          colWidth = 0x0,
          actualWidth = 0x0,
          nWidth = 0x0,
          nullValue = '\000' <repeats 19 times>,
          outfile = '\000' <repeats 4095 times>,
          pStmt = 0x0,
          pLog = 0x0,
          aAuxDb = {{
              db = 0x0,
              zDbFilename = 0x555555710963 ":memory:",
              zFreeOnClose = 0x0
            }, {
              db = 0x0,
              zDbFilename = 0x0,
              zFreeOnClose = 0x0
            }, {
              db = 0x0,
              zDbFilename = 0x0,
              zFreeOnClose = 0x0
            }, {
              db = 0x0,
              zDbFilename = 0x0,
              zFreeOnClose = 0x0
            }, {
              db = 0x0,
              zDbFilename = 0x0,
              zFreeOnClose = 0x0
          pAuxDb = 0x7fffffffdff8,
          aiIndent = 0x0,
          nIndent = 0x0,
          iIndent = 0x0,
          zNonce = 0x0,
          sGraph = {
            pRow = 0x0,
            pLast = 0x0,
            zPrefix = '\000' <repeats 99 times>
          expert = {
            pExpert = 0x0,
            bVerbose = 0x0
        zInitFile = 0x0
        i = 0x1
        rc = 0x0
        warnInmemoryDb = 0x1
        readStdin = 0x1
        nCmd = 0x0
        azCmd = 0x0
        zVfs = 0x0
        __PRETTY_FUNCTION__ = "main"
#6  0x00007ffff7c00083 in __libc_start_main (main=0x5555555a3d60 <main>, argc=0x1, argv=0x7fffffffe228, init=<optimized out>, fini=<optimized out>, 
    rtld_fini=<optimized out>, stack_end=0x7fffffffe218) at ../csu/libc-start.c:308
        self = <optimized out>
        result = <optimized out>
        unwind_buf = {
          cancel_jmp_buf = {{
              jmp_buf = {0x55555570e3b0, 0x57da55cf80eeb113, 0x555555568ea0, 0x7fffffffe220, 0x0, 0x0, 0xa825aa30426eb113, 0xa825ba4f8080b113},
              mask_was_saved = 0x0
          priv = {
            pad = {0x0, 0x0, 0x1, 0x7fffffffe228},
            data = {
              prev = 0x0,
              cleanup = 0x0,
              canceltype = 0x1
        not_first_call = <optimized out>
#7  0x0000555555568ece in _start ()
No symbol table info available.

Anyway, we appreciate the quick bug fix and the fast reply. Thank you!

(9) By anonymous on 2022-11-01 03:48:51 in reply to 5 [link] [source]

Sorry for the delayed response (was out for the day). This post is just to clear up your question, although it appears moot at this point.

Yes, similar to Jose's example (I could have made that more clear, my apologies) and that it did not recreate Yu's behavior.

My intent was to note that jose's example was similar in the wasm fiddle.


(10) By bucweat on 2022-11-01 13:14:41 in reply to 5 [link] [source]

I was able to reproduce this in VS2019 on Windows with a very similar stack trace.

Not sure if this was obvious or not or maybe I'm missing something... but the trick to reproduce is to run the query from a file as defined by the OP:

PRAGMA hard_heap_limit=1

Running just the PRAGMA in the CLA is not the same as it is missing the extra 0. Not sure if the OP meant to have that 0 in his query file...