Tutorial :VS2010 C code - String pooling



Question:

Below code crash in VS 2010 when you compile with following flag and if you add /GF- or remove the opimization flag they don't crash. The crash occur at assembly code which translate 'if( path[i] == '/' )'. I like to understand the optimization that compiler does here and lead to crash. Looking forward for some pointers.

-Karthik

cl.exe /MD /O2 test.c

// Test.c

#include <stdio.h>    #include  <string.h>    void testpath(char* path, int bufsiz)    {          int i;          printf("%p\n", path);        for( i=0; i < strlen(path); i++ ) {          if( path[i] == '/' ) {             path[i] = '\\';         }      }    }    int main()    {          const char* path = "testexport.prj";        char *path1 = "testexport.prj";        printf("%p\n", path);        printf("%p\n", path1);        testpath(path, 1024);    }    


Solution:1

Trying to modify the contents of a string literal invokes Undefined Behaviour.

From ISO C99 (Section 6.4.5/6)

It is unspecified whether these arrays are distinct provided their elements have the appropriate values. If the program attempts to modify such an array, the behavior is undefined

From ISO C++-98 (Section 2.13.4/2)

Whether all string literals are distinct(that is, are stored in non overlapping objects) is implementation defined. The effect of attempting to modify a string literal is undefined.

On most implementations (including MSVC) this results to crash of your application.


Solution:2

You try to modify a string literal, that's undefined behavior.

 const char* path = "testexport.prj";   testpath(path, 1024);   // then later:   void testpath(char* path, int bufsiz)   {       int i;         for( i=0; i`<`strlen(path); i++ ) {         if( path[i] == '/' ) {             path[i] = '\\';// <<<<<< UB here       }     }    

string literals are usually stored in read-only memory, so on your implementation an attempt to modify a string literal results in access violation that crashes your program.


Solution:3

We have an application where in VC6.0 there appears to be a bug in string pooling. Two different strings appear to "pool" to one string, causing a crash. This crash does not occur in VS2010. OR if /Zi is used in VS6.0 instead of /ZI. Just wondering if the default in VS6.0 is to use string pooling and not the default in VS2010. In which case it could be that the string pooling bug still exists. If there are MANY strings which are near identical, the working theory I have (yet to be vetted) is that there is a hash collision going undetected in the string pooling, which eliminates one of the two strings. This would be visible in the generated ASM code when looking at the pointers for two nearly similar strings. In our case we are not modifying strings in VC6.0, just referencing them.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »