zlib's gzseek return gabbage and fails intermittently under wine.

Nikolay Sivov bunglehead at gmail.com
Mon Apr 15 01:18:26 CDT 2013


On 4/15/2013 02:50, Hin-Tak Leung wrote:
> --- On Sun, 14/4/13, Vincent Povirk <madewokherd at gmail.com> wrote:
>
>> Well, here's a simple thing you can
>> check: Does your zlib dll link to
>> _lseek or _lseeki64? The first one uses a 32-bit offset.
>> Wine's
>> implementation (http://source.winehq.org/source/dlls/msvcrt/file.c#L1090)
>> expands that to 64-bit and later truncates the file offset
>> to 32-bit.
>> For a file larger than 2 GB, that could account for the
>> large negative
>> value you're seeing.
>>
>> And since this would only matter in cases where zlib uses
>> lseek (the
>> first time through I guess it wouldn't, as it has to read
>> the whole
>> everything up to the offset you give at least once) and is
>> at least 2
>> GB into the file, that might also explain why it doesn't
>> fail
>> initially.
>>
>> But without really digging into the zlib code, all I can do
>> it speculate.
>>
>> I should probably also check coapp's build of zlib
>> sometime.
> It is not a dll - as you suggested and I already wrote, due to past experience of other's packaging of slightly outdated, it is being built against a private *source* copy of the latest zlib.
>
> Also the bogus offset is not large negative but large (larger than 2^32) positive.
>
> Here is an example of the debug output under wine:
>
> ---------------
> set_filepos failed at 34307 returning 134127533721091
> Re-opening to re-try
> Retry successful
> set_filepos failed at 96919 returning 146686018157207
> Re-opening to re-try
> Retry successful
> set_filepos failed at 128254 returning 12103217968382
> Re-opening to re-try
> Retry successful
> ...
> ---------------
>
> This is generated by this code snipplet which is called inside a loop, all wrapped in the c++ class:
>
> ---------------
> 		off_t offset = gzseek(gzvcf_in, filepos, SEEK_SET);
> 		if (offset != filepos) { //implicitly converted to off_t by template streamoff()
> 		    LOG.printLOG("set_filepos failed at " + LOG.streampos2str(filepos)
> 		      + " returning " + LOG.off_t2str(offset) + "\n");
> 		    LOG.printLOG("Re-opening to re-try\n");
> 		    close(); open();
> 		    off_t offset1 = gzseek(gzvcf_in, filepos, SEEK_SET);
> 		    if (offset1 == filepos)
> 		      LOG.printLOG("Retry successful\n");
> 		    else
> 		      LOG.error("Retry failed\n"); // this also aborts
> 		}
>
> -------------------
>
> This code runs silently on linux i.e. the "if (offset != filepos)" condition is not triggered.
For windows build you'll need to define _WIN32, so _lseeki64 is used by 
zlib. After this done you could play with
native msvcrt to see if it helps, and after that +relay will tell you 
everything.



More information about the wine-devel mailing list