strtok DEBUG implementation bug? 
Author Message
 strtok DEBUG implementation bug?

Here's an absolute beauty.  The following code breaks under MSVC++ 6.0.  Can
anyone explain why?.

int Filevercmp (char *szCheckVer, char *szMinimumVer)
{
  int CheckVersion = 0;
  int CheckMinorRev = 0;
  int CheckMajorRev = 0;
  int MinimumVersion = 0;
  int MinimumMinorRev = 0;
  int MinimumMajorRev = 0;

  CheckVersion = atoi (strtok (szCheckVer, "."));
  CheckMajorRev = atoi (strtok (NULL, "."));
  CheckMinorRev = atoi (strtok (NULL, "."));

  // this next line causes an invalid memory access!!
  MinimumVersion = atoi (strtok (szMinimumVer, "."));
  MinimumMajorRev = atoi (strtok (NULL, "."));
  MinimumMinorRev = atoi (strtok (NULL, "."))

  more stuff...

Quote:
}

when debugging into the C run-time library for strtok() it would appear that
an invalid memory access violation occurs trying to set the search character
just found (look at the code where it happens) to NULL so the token can be
returned.  This did not happen under neither MSVC4.2 nor MSVC5.0.

Regards,

Alex



Sun, 01 Apr 2001 03:00:00 GMT  
 strtok DEBUG implementation bug?

Quote:

>Here's an absolute beauty.  The following code breaks under MSVC++ 6.0.  Can
>anyone explain why?.

It's a beauty, alright.  It beautifully shows how ready some people
are to blame somebody else for problems of their own creation.

Note that the following function expects a non-const 2nd argument.
I suspect that it has been called with some pointer that directly
references the resource section of an .exe.  Appropriate use of
const might have illuminated the real problem much sooner.

Quote:
>int Filevercmp (char *szCheckVer, char *szMinimumVer)
>{
>  int CheckVersion = 0;
>  int CheckMinorRev = 0;
>  int CheckMajorRev = 0;
>  int MinimumVersion = 0;
>  int MinimumMinorRev = 0;
>  int MinimumMajorRev = 0;

>  CheckVersion = atoi (strtok (szCheckVer, "."));
>  CheckMajorRev = atoi (strtok (NULL, "."));
>  CheckMinorRev = atoi (strtok (NULL, "."));

>  // this next line causes an invalid memory access!!
>  MinimumVersion = atoi (strtok (szMinimumVer, "."));
>  MinimumMajorRev = atoi (strtok (NULL, "."));
>  MinimumMinorRev = atoi (strtok (NULL, "."))

>  more stuff...
>}

The strok() function is documented and prototyped as if it
may modify the memory referenced by the first argument.
  char *strtok( char *strToken, const char *strDelimit );
You don't mention what you have passed to it, but I am
pretty sure you passed in read-only memory.  That is
why you see the access fault.

Quote:
>when debugging into the C run-time library for strtok() it would appear that
>an invalid memory access violation occurs trying to set the search character
>just found (look at the code where it happens) to NULL so the token can be
>returned.  This did not happen under neither MSVC4.2 nor MSVC5.0.

That does not make it OK to have passed unmodifiable memory
to strtok with earlier versions.

--Larry Brasfield
Above opinions may be mine alone.



Sun, 01 Apr 2001 03:00:00 GMT  
 strtok DEBUG implementation bug?


Quote:
>Here's an absolute beauty.  The following code breaks under MSVC++ 6.0.
Can
>anyone explain why?.

>int Filevercmp (char *szCheckVer, char *szMinimumVer)
>{
>[snipped]
>  // this next line causes an invalid memory access!!
>  MinimumVersion = atoi (strtok (szMinimumVer, "."));
>  MinimumMajorRev = atoi (strtok (NULL, "."));
>  MinimumMinorRev = atoi (strtok (NULL, "."))
>[snipped]

Where is szMinimumVer coming from?  Is it a valid pointer to non-read-only
memory?  strtok does modify the first argument (it puts NULL bytes in as
place holders), and will {*filter*}if you pass in a string that lives in some
read-only memory.  Try allocating your own string variable locally within
the Filevercmp function and strcpy'ing the szMinimumVer variable into it and
strtok'ing it.

I do not personally have VC++ 6.0, but these are just some of my suggestions
as to what the problem may be.

Peace,
--michael



Sun, 01 Apr 2001 03:00:00 GMT  
 strtok DEBUG implementation bug?
That is absolutely right.  It is read-only memory.  It still does not
explain why it does not work anymore which is what the question is all
about.

FYI:
I was calling Filevercmp with something like this:

#define MINIMUM_VERSION         "1.0.3"

GetPrivateProfileString ("Version", "FileVersion", "0.0.0", szVersion, 10,
  "MYPROFILE.INI");
int nResult = Filevercmp (szVersion, MINIMUM_VERSION);


Quote:
>Here's an absolute beauty.  The following code breaks under MSVC++ 6.0.
Can
>anyone explain why?.

>int Filevercmp (char *szCheckVer, char *szMinimumVer)
>{
>  int CheckVersion = 0;
>  int CheckMinorRev = 0;
>  int CheckMajorRev = 0;
>  int MinimumVersion = 0;
>  int MinimumMinorRev = 0;
>  int MinimumMajorRev = 0;

>  CheckVersion = atoi (strtok (szCheckVer, "."));
>  CheckMajorRev = atoi (strtok (NULL, "."));
>  CheckMinorRev = atoi (strtok (NULL, "."));

>  // this next line causes an invalid memory access!!
>  MinimumVersion = atoi (strtok (szMinimumVer, "."));
>  MinimumMajorRev = atoi (strtok (NULL, "."));
>  MinimumMinorRev = atoi (strtok (NULL, "."))

>  more stuff...
>}

>when debugging into the C run-time library for strtok() it would appear
that
>an invalid memory access violation occurs trying to set the search
character
>just found (look at the code where it happens) to NULL so the token can be
>returned.  This did not happen under neither MSVC4.2 nor MSVC5.0.

>Regards,

>Alex



Sun, 01 Apr 2001 03:00:00 GMT  
 strtok DEBUG implementation bug?

Quote:

>That is absolutely right.  It is read-only memory.  It still does not
>explain why it does not work anymore which is what the question is all
>about.

Lookup the /GF and /Gf compiler options.  You most likely
have a wizard-generated project which has enabled a
new VC6 feature whereby string literals can be pooled
and placed into read-only memory.  A better option than
disabling that worthy feature is to modify your code as I
indicate below.

Quote:
>FYI:
>I was calling Filevercmp with something like this:

///>#define MINIMUM_VERSION         "1.0.3"
char MINIMUM_VERSION[] = "1.0.3";

Then, be sure you call your Filevercmp() only once
because that char array will be modified as a side
effect of the call.  It will not run the same way again.

Quote:
>GetPrivateProfileString ("Version", "FileVersion", "0.0.0", szVersion, 10,
>  "MYPROFILE.INI");
>int nResult = Filevercmp (szVersion, MINIMUM_VERSION);

--Larry Brasfield
Above opinions may be mine alone.



Sun, 01 Apr 2001 03:00:00 GMT  
 strtok DEBUG implementation bug?
6.0 is more up to the C++ standard I have heard, so we aren't going to be
able to get over like we have been in the past.


Sun, 01 Apr 2001 03:00:00 GMT  
 strtok DEBUG implementation bug?

Quote:

>That is absolutely right.  It is read-only memory.  It still does not
>explain why it does not work anymore which is what the question is all
>about.

    No... The real question is why did it work before, when it shouldn't
have.

--
Truth,
   James [MVP]
http://www.NJTheater.Com       -and-
http://www.NJTheater.Com/JamesCurran

begin 666 James M. Curran.vcf


M4DLZ.SLQ."!*;VAN(%-T+"!3=6ET92 R0CM";&]O;69I96QD.TY*.S W,# S
M+34Q-#D-"DQ!0D5,.U=/4DL[14Y#3T1)3D<]455/5$5$+5!224Y404),13HQ
M."!*;VAN(%-T+"!3=6ET92 R0CTP1#TP04)L;V]M9FEE;&0L($Y*(# W,# S
M+34Q-#D-"E523#IH='1P.B\O=W=W+DY*5&AE871E<BYC;VTO2F%M97-#=7)R
M86X-"E523#IH='1P.B\O=W=W+DY*5&AE871E<BYC;VT-"D5-04E,.U!2148[
M24Y415).150Z2F%M97-#=7)R86Y 0V]M<'5397)V92YC;VT-"E)%5CHQ.3DX

`
end



Sun, 01 Apr 2001 03:00:00 GMT  
 strtok DEBUG implementation bug?
On Wed, 14 Oct 1998 09:51:51 -0400, "James Curran"

Quote:


>>That is absolutely right.  It is read-only memory.  It still does not
>>explain why it does not work anymore which is what the question is all
>>about.

>    No... The real question is why did it work before, when it shouldn't
>have.

Undefined behaviour includes "working"...

-- Mat.



Sun, 01 Apr 2001 03:00:00 GMT  
 strtok DEBUG implementation bug?

Quote:

> >    No... The real question is why did it work before, when it shouldn't
> >have.

> Undefined behaviour includes "working"...

Yes, I wish people would learn that "I got away with it"
is not equivlent with "complaint with the standard."


Sun, 01 Apr 2001 03:00:00 GMT  
 strtok DEBUG implementation bug?

Quote:


>>That is absolutely right.  It is read-only memory.  It still does not
>>explain why it does not work anymore which is what the question is all
>>about.

>    No... The real question is why did it work before, when it shouldn't
>have.

It worked before because, before VC6, pooled string literals
were not placed in read-only memory.  Alex was passing a
string literal to a routine that attempted to modify it.  This
"worked" when string literals could be modified even though
mutability is not guaranteed by the language.  IIRC, writing
to them yields undefined behavior.

--Larry Brasfield
Above opinions may be mine alone.



Sun, 01 Apr 2001 03:00:00 GMT  
 strtok DEBUG implementation bug?
On Wed, 14 Oct 1998 17:45:01 GMT, "Larry Brasfield"

Quote:

>It worked before because, before VC6, pooled string literals
>were not placed in read-only memory.  Alex was passing a
>string literal to a routine that attempted to modify it.  This
>"worked" when string literals could be modified even though
>mutability is not guaranteed by the language.  IIRC, writing
>to them yields undefined behavior.

String literals are constants, although their apparent type is char *,
rather than const char *; I understand that this was a concession in
C89/90 to avoid type mismatches in legacy code. But since they are
constants, an attempt to write to them does invoke undefined
behaviour.

-- Mat.



Sun, 01 Apr 2001 03:00:00 GMT  
 strtok DEBUG implementation bug?

Quote:

>String literals are constants, although their apparent type is char *,
>rather than const char *; I understand that this was a concession in
>C89/90 to avoid type mismatches in legacy code. But since they are
>constants, an attempt to write to them does invoke undefined
>behaviour.

In Standard C++, the type of a string literal is const char[n], where n is
the size of the literal, which is quite different than a pointer, const or
not. For backward compatibility, there is an unfortunate, but deprecated,
conversion to char*. I think it would be a good idea for compilers to warn
about this conversion.

--
Doug Harrison



Sun, 01 Apr 2001 03:00:00 GMT  
 strtok DEBUG implementation bug?

Quote:


>>String literals are constants, although their apparent type is char *,
>>rather than const char *; I understand that this was a concession in
>>C89/90 to avoid type mismatches in legacy code. But since they are
>>constants, an attempt to write to them does invoke undefined
>>behaviour.

>In Standard C++, the type of a string literal is const char[n], where n is
>the size of the literal, which is quite different than a pointer, const or
>not.

Actually, that's close to the mark in C too. I misremembered the
content of the standard. Quoting from ISO sec. 6.1.4,

| [...] The multibyte character sequence is then used to initialize an array
| of static storage duration and length just sufficient to contain the
| sequence. For character string literals, the array elements have type char
| and are initialised with the individual bytes of the character sequence;
| [...]

So, the closest match in type is static char[ len ], where len is the
length of the sequence (including terminator).

-- Mat.



Sun, 01 Apr 2001 03:00:00 GMT  
 strtok DEBUG implementation bug?

Quote:
> >That is absolutely right.  It is read-only memory.  It still does not
> >explain why it does not work anymore which is what the question is
all
> >about.
>     No... The real question is why did it work before, when it
shouldn't
> have.

String literals only get moved to read-only memory if you compile with
'/GF' so the problem would have happened in VC5 if that had been set.

Looking at my copy of the October '98 MSJ the article on VC6 indicates
that the new 'Edit & Continue' feature in VC6 uses a new compile option
'/ZI' which replaces '/Zi' and enables '/GF' and '/Gy' (function-level
linking).  I can't verify that but I assume that's what causes the
problem in debug builds.

Mike.



Mon, 02 Apr 2001 03:00:00 GMT  
 
 [ 14 post ] 

 Relevant Pages 

1. strtok() and while() (compiler bug ?)

2. strtok() BUG or FEATURE??!?!?

3. BUG: Managed C++ Explicit Interface Implementations on Nested Classes

4. Bug in the implementation of __hook and __unhook for COM events

5. BUG!!! in VC++6.0 function template implementation

6. bug in STL implementation?

7. Bug in _bstr_t implementation

8. bug in _bstr_::copy implementation in VC5 (w/fix)

9. The CString implementation bug (multithreading crash)!

10. Multiple levels of implementation and implementation inheritance

11. BUG: DEBUG member in enum in class syntax error C2059

12. Bug appears when compiled with no debug info

 

 
Powered by phpBB® Forum Software