View Ticket
Ticket Hash: c62c5e58524b204dbc3a3ed195f3bc55fcbc1511
Title: Debug assertion sqlite3VdbeMemAboutToChange: Assertion `(mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z)' failed (2)
Status: Fixed Type: Code_Defect
Severity: Minor Priority: Immediate
Subsystem: Unknown Resolution: Fixed
Last Modified: 2019-12-23 02:30:51
Version Found In: 3.30.0
User Comments:
mrigger added on 2019-12-22 23:05:59:

Consider the following test case:

PRAGMA encoding = 'UTF16';
INSERT INTO t0(c0) VALUES (0), (0); -- sqlite3.c:75871: sqlite3VdbeMemAboutToChange: Assertion `(mFlags&MEM_Str)==0 || (pMem->n==pX->n && pMem->z==pX->z)' failed.

When compiling with -DSQLITE_DEBUG, the INSERT triggers an assertion error. The assert triggered seems to be the same as in [5ad2aa6921].

drh added on 2019-12-23 02:30:51:

This is a deficiency in testing and verification logic only. Release builds that omit the testing and verification logic appear to work correctly.

The sqlite3VdbeMemAboutToChange() subsystem attempts to verify that after a shallow copy (an OP_SCopy) from one register to another, the source register does not change before the last access of the destination register. A "shallow copy" means that large strings or BLOBs are copied by reference instead of by value. Shallow copies are a performance optimization.

No actual defects were discovered. In other words, no examples of doing the following illegal operation were found:

  1. Shallow copy A into B
  2. Change the value of A
  3. Read the value in B

To put it another way, this ticket describes a false-positive in the mechanism used to detect problems in shallow copies such as the above.

A previous ticket [5ad2aa6921faa1ee] also described a similar false-positive. The initial fix to that prior ticket was to change the shallow-copy into a deep-copy (change a copy-by-reference into a copy-by-value), thus avoiding the false-positive. With the enhancements to sqlite3VdbeMemAboutToChange() logic to reduce the number of false-positives, the fix for [5ad2aa6921faa1ee] could be backed out since the enhancements to the sqlite3VdbeMemAboutToChange() mechanism in check-in [5ad2aa6921faa1ee] fix both false-positives.