SQLite Forum

sessionfuzz fails on some architectures (ARM, PPC, SPARC)
Login
Can you please try the patch at 
[check-in 40c44d38104dfcb6](https://www.sqlite.org/src/info/40c44d38104dfcb6)
and let me know if it works better for you on your platforms?  I am only
able to confirm the problem on ARM using GCC 8.3.0 and -O2.

Other potential workarounds for this problem include:

  *   Use an earlier version of GCC that does not have the bug.
  *   Use -Os instead of -O2

Unfortunately, I do not at this time have a simple test case to demonstrate
the GCC problem.  The easiest demonstration I have is the following:

  1.  Download <https://sqlite.org/tmp/gcc-problem-20200723/sftest.c> (7.8MB)
      and <https://sqlite.org/tmp/gcc-problem-20200723/data1.db> (252KB).
  2.  Compile using: "`$GCC -O2 sftest.c`"
  3.  Run like this: "`./a.out run data1.db`"

If you uncomment the "SQLITE_NOINLINE" macro (which resolves to
`__attribute__((noinline))` for gcc) on line 97448 of the sftest.c
file then it works.  If you change the
-O2 on step 2 to anything else, it appears to work as well.

The problem appears to be here:

~~~~~
57504    if( !isOpen(pPager->jfd) ){
57505      if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){
57506        sqlite3MemJournalOpen(pPager->jfd);
57507      }else{
57508        int flags = SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE;
57509        int nSpill;
57510
57511        if( pPager->tempFile ){
57512          flags |= (SQLITE_OPEN_DELETEONCLOSE|SQLITE_OPEN_TEMP_JOURNAL);
57513          nSpill = sqlite3Config.nStmtSpill;
57514        }else{
57515          flags |= SQLITE_OPEN_MAIN_JOURNAL;
57516          nSpill = jrnlBufferSize(pPager);
57517        }
57518
57519        /* Verify that the database still has the same name as it did when
57520        ** it was originally opened. */
57521        rc = databaseIsUnmoved(pPager);
57522        if( rc==SQLITE_OK ){
57523          rc = sqlite3JournalOpen (
57524              pVfs, pPager->zJournal, pPager->jfd, flags, nSpill
57525          );
57526        }
57527      }
57528      assert( rc!=SQLITE_OK || isOpen(pPager->jfd) );
57529    }
~~~~~

The assert() on line 57528 is the one that is failing in the Gentoo bug
reports.  The `isOpen()` is a macro: 

~~~~~
   #define isOpen(X) ((X)->pMethods!=0)
~~~~~

So on line 57504, pMethods is NULL.  But it gets changed to non-NULL by the
sqlite3MemJournalOpen() call on line 57506.  My best guess is that the gcc
optimizer does not understand that the value of pMethods might (and does) change
and so it remembers the prior NULL value and uses it in the assert() on line
57528, causing the assert() to fail even though pMethods is now non-NULL.
Preventing the sqlite3MemJournalOpen() call from being inlined clears the
problem.