javaj1811 at elxala.com wrote:
> ales at elxala.de wrote:
>> Hi, this is actually a Ticket, the good new is that is already 
>> pre-analyzed
>> and probably also the cause has been found.
>> I hope this is the right place to put this
>>
>> TITLE: Wrong ERROR_DISK_FULL writing a blob on Windows
>>
>> DESCRIPTION:
>>
>>    Having a sqlite database about 4.1 GB
>>    writing blobs in some table, for instance using a statement like
>>       INSERT INTO inodeCargo VALUES (1000, readfile ("ScreenShot.png"));
>>
>>    an error ERROR_DISK_FULL can be through wrongly (under certain 
>> conditions)
>>
>>    Windows 7 64-bit
>>
>> REPRODUCIBLE:
>>    When the conditions are met, always reproducible
>>
>>
>> CAUSE :
>>
>>    windows function WriteFile return error 112 (ERROR_DISK_FULL) when 
>> trying to write
>>    1024 bytes using a offset = 4294966272 = 0xFFFFFC00 = FFFFFFFF - 2023
>>
>>    This was observed using the default mode (OVERLAPPED) although a 
>> test compiling
>>    the code with
>>       #define SQLITE_WIN32_NO_OVERLAPPED
>>    at the begining also failed.
>>
>> PATCH:
>>
>>    The patch (see sqlite3_modified.c) work in my case, but obviously 
>> cannot
>>    fix the mode NO_OVERLAPPED (it does not compile in this mode). 
>> Also all procedures
>>    using the buggy function (if this result to be the cause) should 
>> be reviewed.
>>    A more precise fix has to be developed by some expert in sqlite code.
>>
>> ANALYSIS:
>>
>>    A sqlite db used to store files came in the conditions described
>>    size of database file : 4.194.303 KB
>>    size of journal file : 8 KB
>>    size of the image (png file) : 4.417 KB
>>
>>    SQL Query returning systematically ERROR_DISK_FULL:
>>       INSERT INTO inodeCargo VALUES (-24, 4522876, 0, readfile 
>> ("ScreenShot320.png"));
>>
>>    (hard disk of the test with about 1 TB free space)
>>
>>    Since the case was 100% reproducible I could debug the problem using
>>    sqlite-amalgamation-3080803.zip (ver 3.8.8.3)
>>    I tried sqlite-amalgamation-201503091040.zip as well with the same
>>    result, so the problem was also not fixed in this pre-release.
>>
>>    In debug session I found that the error came from
>>
>>       static int winWrite (...
>>
>>    and it is given in the line
>>
>>       if( !osWriteFile(pFile->h, aRem, nRem, &nWrite, &overlapped) ){
>>
>>    which is a call to a windows api function WriteFile
>>
>>    adding the extra debug messages into a file (see 
>> sqlite3_modified.c function "static int winWrite")
>>    this was the output before the fail (ERROR_DISK_FULL)
>>
>> ...
>> WRITE file=00000030, buffer=00EDBE08, amount=1024, offset=4294965248, 
>> lock=4
>> OVERLAPPED offset=4294965248, OffsetHigh=0
>> WRITE file=00000030, buffer=00EDC2E0, amount=1024, offset=4294966272, 
>> lock=4
>> OVERLAPPED offset=4294966272, OffsetHigh=0
>>
>>    Now note that
>>
>>       4294966272 = 0xFFFFFC00
>>       and FFFFFFFF - FFFFFC00 = 3FF = 1023 !!!!! and we want to write 
>> 1024 bytes!!!
>>
>>
>> That this is a Microsoft bug is only a guess for what I have seen 
>> debugging the code,
>> anyway if not I hope this analysis helps to find it the final cause 
>> of the problem and it could be fixed.
>>
>> Regards
>> Alejandro
>>
>>
>>
>>
>>
>>
>>
>> _______________________________________________
>> sqlite-users mailing list
>> sqlite-users at mailinglists.sqlite.org
>> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
> In the previous email (from another account of mine) I did attach a 
> zipped sqlite3_modified.c that
> did not appear in the email published, maybe because of its size about 
> 1MB although it was 7zipped
> anyway, now I attach the code of only function modified in sqlite3.c 
> amalgamation: winWrite
> here the relevant code where the patch lies
>
>
> #if !SQLITE_OS_WINCE && !defined(SQLITE_WIN32_NO_OVERLAPPED)
>     memset(&overlapped, 0, sizeof(OVERLAPPED));
>     overlapped.Offset = (LONG)(offset & 0xffffffff);
>     overlapped.OffsetHigh = (LONG)((offset>>32) & 0x7fffffff);
>
>    // PATCH  !! ------------
>    //
>     if (((LONG)0xffffffff - (LONG)overlapped.Offset) < nRem)
>       nRem = ((LONG)0xffffffff - (LONG)overlapped.Offset);
>    // -----------
>
>
>    // EXTRA DEBUG ------------
>    //
>    FILE * fout = fopen("salgo.txt", "at");
>     if (fout != 0)
>     {
>         fprintf(fout, "OVERLAPPED offset=%u, OffsetHigh=%u\n", 
> overlapped.Offset, overlapped.OffsetHigh);
>         fclose(fout);
>     }
>    // -----------
>
> #endif
>
>
>
> _______________________________________________
> sqlite-users mailing list
> sqlite-users at mailinglists.sqlite.org
> http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users
also specify that the exact error given by sqlite in this problem is

#define SQLITE_FULL        13   /* Insertion failed because database is 
full */
     /* SQLITE_FULL        */ *"database or disk is full",*

which is produced by the windows api error ERROR_DISK_FULL

Reply via email to