Ticket #2133 (new defect)

Opened 8 months ago

Last modified 5 months ago

crash on GDALOpen of GeoTIFF in WinCE build

Reported by: fbausch Assigned to: mloskot
Priority: normal Milestone:
Component: WinCE Port Version: 1.5.0
Severity: normal Keywords: gtiff wince
Cc: warmerdam

Description (Last modified by mloskot)

when using Windows CE build of GDAL 1.5.0 (also 1.4.4) on GDALOpen of GeoTIFF file in Windows Mobile 6, uncaught exception causes crash.

No problems encountered when using GDAL 1.4.2.
using Visual Studio 2005, debugging in WM6 Professional emulator

crash seems to be prompted by call to wceex_bsearch with num parameter=0, which is not valid, suggesting the problem must lie upstream of the call to bsearch.

call stack:

GPSMap.exe!wceex_bsearch(const void* key = 0x1e1cde2c, const void* base = 0x00212740, unsigned int num = 0, unsigned int width = 4, int (const void*, const void*)* compare = 0x000f32ec) Line: 58, Byte Offsets: 0x10	C

GPSMap.exe!TIFFFindField(tiff* tif = 0x00212460, unsigned int tag = 254, TIFFDataType dt = 0) Line: 483, Byte Offsets: 0x144	C

GPSMap.exe!_TIFFMergeFields(tiff* tif = 0x00212460, _TIFFField* info = 0x00196920, unsigned int n = 138) Line: 354, Byte Offsets: 0x168	C

GPSMap.exe!_TIFFSetupFields(tiff* tif = 0x00212460, _TIFFFieldArray* fieldarray = 0x00195784) Line: 292, Byte Offsets: 0x134	C

GPSMap.exe!TIFFDefaultDirectory(tiff* tif = 0x00212460) Line: 1101, Byte Offsets: 0x38	C

GPSMap.exe!TIFFReadDirectory(tiff* tif = 0x00212460) Line: 3368, Byte Offsets: 0x15c	C

GPSMap.exe!TIFFClientOpen(const char* name = 0x001fed10, const char* mode = 0x0016a518, void* clientdata = 0x001fef10, long int (void*, void*, long int)* readproc = 0x000de2c4, long int (void*, void*, long int)* writeproc = 0x000de300, unsigned long int (void*, unsigned long int, int)* seekproc = 0x000de33c, int (void*)* closeproc = 0x000de39c, unsigned long int (void*)* sizeproc = 0x000de3cc, int (void*, void**, unsigned long int*)* mapproc = 0x000de438, void (void*, void*, unsigned long int)* unmapproc = 0x000de45c) Line: 464, Byte Offsets: 0xc44	C

GPSMap.exe!XTIFFClientOpen(const char* name = 0x001fed10, const char* mode = 0x0016a518, void* thehandle = 0x001fef10, long int (void*, void*, long int)* RWProc = 0x000de2c4, long int (void*, void*, long int)* RWProc2 = 0x000de300, unsigned long int (void*, unsigned long int, int)* SProc = 0x000de33c, int (void*)* CProc = 0x000de39c, unsigned long int (void*)* SzProc = 0x000de3cc, int (void*, void**, unsigned long int*)* MFProvc = 0x000de438, void (void*, void*, unsigned long int)* UMFProc = 0x000de45c) Line: 184, Byte Offsets: 0x58	C

GPSMap.exe!VSI_TIFFOpen(const char* name = 0x001fed10, const char* mode = 0x0016a518) Line: 145, Byte Offsets: 0x1d0	C++

GPSMap.exe!GTiffDataset::Open(GDALOpenInfo* poOpenInfo = 0x1e1ce1f8) Line: 2855, Byte Offsets: 0x250	C++

GPSMap.exe!GDALOpen(const char* pszFilename = 0x001fecd0, GDALAccess eAccess = 0) Line: 1774, Byte Offsets: 0x10c	C++

Change History

01/04/08 20:27:36 changed by warmerdam

  • keywords set to gtiff wince.
  • status changed from new to assigned.
  • component changed from default to WinCE Port.
  • cc set to mloskot.

01/04/08 20:31:23 changed by warmerdam

I see that TIFFFindField() can easily call bsearch() with num=0, but it isn't clear to me why this should cause a problem. Perhaps the wceex_bsearch() implementation needs handling for this case?

I can fix libtiff if it can be demonstrated that it is inappropriate to call bsearch() this way.

01/04/08 20:34:15 changed by mloskot

  • description changed.

01/04/08 20:42:47 changed by warmerdam

Can you confirm you are using the same wceex_bsearch() implementation found at:

http://wcelibcex.svn.sourceforge.net/viewvc/wcelibcex/trunk/src/wce_bsearch.c?view=markup

This seems to have an assert on line 58, and I don't see how anything could go wrong with the parameters in your traceback. In particular if num=0, then left=0, right=-1, and the loop should be skipped resulting in the function safely returning NULL.

Perhaps you have an old (buggy) version of wcelibcex?

Mloskot notes in IRC:

<mloskot> FrankW:  if num is 0, then right = -1
<mloskot> and NULL is returned
<mloskot> because while condition is false on start
<mloskot> while (0 <= -1)
<mloskot> and no searching is issues
<mloskot> issued
<mloskot> that's my diagnosis but I've no idea why num is 0 - the most important part ;-)
<mloskot> FrankW:  AFAIK, my bsearch function works as POSIX defines it
<mloskot> http://www.opengroup.org/onlinepubs/000095399/functions/bsearch.html
<mloskot> "If the nel argument has the value zero, the comparison function pointed to by compar shall not be called and no match shall be found."
<mloskot> where "nel" is my num
<mloskot> and null pointer is returned if no match found

This matches my understanding. So I'm left not knowing why things are crashing as you see.

At least you should try to establish if it is an assert() triggering the crash or something else.

01/04/08 20:50:00 changed by mloskot

I've not tested GTiff driver under Windows CE since 1.4.2. I'm back home in Sunday and then I will be able to test it.

fbausch,

It would be helpful and faster for me if I could use the same file as you do. Could you send me one?

01/05/08 21:13:09 changed by warmerdam

  • status changed from assigned to new.
  • owner changed from warmerdam to mloskot.
  • cc changed from mloskot to warmerdam.

fbauche writes:

i am using the wcelibcex 1.0, and it appears that right is unsigned - and instead of holding the value -1, is instead holding a vary large positive value.

i do not think it is an assert failing, rather an infinite loop. the thread dies without allowing any access through the debugger - and the call stack provided is not the stack after the crash, but the stack before it enters into the loop in which the crash happens.

thanks for your attention - i'm happy to continue working to isolate this problem.

f.

---

Your analysis is correct. wce_bsearch needs to check for the case of num==0 since size_t is (at least on some systems) unsigned. I hadn't considered this. Turning over to Mateusz to correct.

01/11/08 17:54:36 changed by fbausch

further work on this points to several issues -
1) in wcelibcex, wce_bsearch needs to check for the case of num==0 since size_t is (at least on some systems) unsigned.
2) in GDAL, frmts/gtiff/libtiff/tif_config.h.wince, #define TIFF_UINT16_T short causes problems, and needs to be <unsigned short>
3)in GDAL, frmts/gtiff/libtiff/tif_dirinfo.c - in the tagCompare routine: when tagCompare is called in this chain: TIFFFindField - bsearch - tagCompare the second return statement appears to be slightly wrong: a wildcard field_type (TIFF_ANY) can be set for the b parameter(the tb tag), which would then allow a field_tag match to return success.
Other call sequences that lead to tagCompare may be different, but in the sequence through TIFFFindField, it is the b parameter which can hold the wildcard type specification, and not the a parameter.
the change below fixes the wildcarding operation
static int tagCompare(const void* a, const void* b) {

const TIFFField* ta = *(const TIFFField**) a; const TIFFField* tb = *(const TIFFField**) b; /* NB: be careful of return values for 16-bit platforms */ if (ta->field_tag != tb->field_tag)

return (int)ta->field_tag - (int)tb->field_tag;

else

// return (ta->field_type == TIFF_ANY) ?
// 0 : ((int)tb->field_type - (int)ta->field_type);

return (tb->field_type == TIFF_ANY) ? // changed return

0 : ((int)tb->field_type - (int)ta->field_type);

}
with these changes, it appears that my problems reading GeoTIFF files are resolved.

04/03/08 08:02:03 changed by wbaer

As already mentioned in #2151 part 2 of the above fix together with the fix in #2151 solved also my gtiff problems on wince.