Bug #28590 call to my_tell() with -1 as file descriptor causes assertion in VC2005
Submitted: 22 May 2007 12:16 Modified: 5 Jun 2007 7:41
Reporter: Ilya Zvyagin Email Updates:
Status: Duplicate Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:5.0-BK OS:Windows (VC 2005 RTL)
Assigned to: Assigned Account CPU Architecture:Any
Tags: Contribution, my_tell open_cached_file init_io_cache

[22 May 2007 12:16] Ilya Zvyagin
Description:
In MySQL server code, my_tell can be called indirectly with 'File fd' parameter == -1. In this case in new version of VC (2005) an assertion arises.

my_bool open_cached_file(IO_CACHE *cache, const char* dir, const char *prefix,
			  uint cache_size, myf cache_myflags)
calls 

if (!init_io_cache(cache,-1,cache_size,WRITE_CACHE,0L,0,
		     MYF(cache_myflags | MY_NABP)))

and then it calls
  pos= my_tell(file, MYF(0));

As the expected result of my_tell in this case is os_off_t(-1), we can simply return it wothout calling CRTL.

How to repeat:
compile in VC 2005 and run script:
--------------------------------------------------
drop table if exists t1;

create table t1( c varchar(100) ) engine=innodb;

select * from t1 order by c;

drop table if exists t1;
--------------------------------------------------

Suggested fix:
my_off_t my_tell(File fd, myf MyFlags __attribute__((unused)))
{
  os_off_t pos;
  DBUG_ENTER("my_tell");
  DBUG_PRINT("my",("Fd: %d  MyFlags: %d",fd, MyFlags));
  if (fd != -1) 
  {
#ifdef HAVE_TELL
    pos=tell(fd);
#else
    pos=lseek(fd, 0L, MY_SEEK_CUR);
#endif
  }
  else
    pos = (os_off_t)-1;

  if (pos == (os_off_t) -1)
    my_errno=errno;
  DBUG_PRINT("exit",("pos: %lu", (ulong) pos));
  DBUG_RETURN((my_off_t) pos);
} /* my_tell */
[22 May 2007 12:52] Valeriy Kravchuk
Thank you for a bug report. Verified just as described on latest 5.0-BK sources. Now this function is:

my_off_t my_tell(File fd, myf MyFlags __attribute__((unused)))
{
  os_off_t pos;
  DBUG_ENTER("my_tell");
  DBUG_PRINT("my",("Fd: %d  MyFlags: %d",fd, MyFlags));
#ifdef HAVE_TELL
  pos=tell(fd);
#else
  pos=lseek(fd, 0L, MY_SEEK_CUR);
#endif
  if (pos == (os_off_t) -1)
    my_errno=errno;
  DBUG_PRINT("exit",("pos: %lu", (ulong) pos));
  DBUG_RETURN((my_off_t) pos);
} /* my_tell */
[5 Jun 2007 7:41] Sergey Vojtovich
A duplicate of BUG#27141.