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