On 12/27/19, Manuel Rigger <rigger.man...@gmail.com> wrote:
> Hi Yongheng and Rui,
>
> This might be a duplicate to a bug that I reported, since both test cases
> trigger the same assertion error. See
> https://sqlite.org/src/tktview?name=37823501c6.

That particular assert() is sort of like an ASAN fault except that it
is for the SQLite byte-code rather than for machine code.  The assert
means that one of the registers in the virtual machine is being used
when it is uninitialized or has been invalidated.  This is usually
harmless, but it is important to find and fix those problems
nevertheless.

Sometimes these warnings are false-positives.  Let me explain:

The byte-code engine has an instruction OP_SCopy that makes a "shallow
copy" of the value in one register into some other register.  The copy
is "shallow" because if it is a string or a blob value, it only copies
a pointer to the string or blob, not the string or blob itself.  This
is an important performance optimization when dealing with large
strings and blobs.

But using OP_SCopy carries risk.   If you OP_SCopy register 1 into
register 2, then you change the value of register 1, then the value in
register 2 is invalid.

When you compile with SQLITE_DEBUG, SQLite adds extra logic that looks
for values that have been invalided after an SCopy.  If you SCopy
register 1 into register 2, then change the value of register 1, then
try to access the value of register 2 in any way, you get the
memIsValid() assertion.  The value of register 2 only truly goes
invalid if the SCopy-ed value was a string or a blob.  But the
memIsValid() mechanism marks the register as invalid regardless of
what kind of value was copied, under the theory that the same SCopy
opcode might copy a string or a blob on a different iteration,
depending on the database content.

The mrigger bug I'm working on right now
(https://www.sqlite.org/src/info/37823501c68a09f9) is an example of
false-positive in this SCopy error detection mechanism.  In that
ticket, the value of virtual column C1 is SCopy-ed from C0.  If that
value is a NULL, then the REPLACE conflict resolution logic causes the
original value for C0 to be replaced by an empty string.  But since C1
was SCopy-ed from C0, that invalidates the value inside of C1, which
causes problems later.  But this is a false positive, because C0 will
only be overwritten in a NOT NULL ON CONFLICT REPLACE constraint if
its original value was NULL.  So the SCopy did not copy a string or a
blob and so there really is no reason to invalidate the C1 register.

So, the https://www.sqlite.org/src/info/37823501c68a09f9 ticket is
really a false-positive in the SCopy misuse validation logic.  It is
still an important ticket and needs to be fixed.  But the problem
would never appear in practice.  It is a bug in logic added by
SQLITE_DEBUG and which does not appear in release builds.

This is the third such false-positive bug like that this month.  The
previous two were:

    https://www.sqlite.org/src/info/5ad2aa6921faa1ee
    https://www.sqlite.org/src/info/c62c5e58524b204d

None of these tickets would have resulted in actual problems in
deployment.  But it is important to fix them, just as it is important
to get your C-code to compile without warnings even though the
warnings in many cases are spurious.  Warnings are often
false-positive, but the warning mechanism does sometimes find real
bugs, so it is helpful to keep it in place.

And, of course, I could bypass all of this heartache by using OP_Copy
(which does a deep copy of the entire value) everywhere instead of
sometimes using OP_SCopy.  Doing so would not make a noticeable
difference for most applications, but it might cause some applications
that deal with lots of large strings and blobs to run slower.  In
other words, these is really all about an optimization.

That last sentence is true about most things we do.  Almost without
exception, bugs found in SQLite arise from our attempts to cut corners
and make it run faster.

-- 
D. Richard Hipp
d...@sqlite.org
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users

Reply via email to