Search code examples
csolariscc

Editing Immutable Strings in C- worked with older compiler but breaks with modern one


I am working with some ancient legacy code that was running on Solaris 10. On the old server, the code compiled and ran without trouble.

The code was then migrated to a Solaris 11 server, where the code still compiles, but when it runs it creates a seg fault core dump.

In both cases, the compiler used was /opt/SUNWspro/bin/cc.

Here is the code snippet:

#include <stdio.h>

char   *blank = "                                   ";

main(argc,argv)
int argc;
char **argv;
{

blank[35] = '\0';
printf("Success.\n");

}

This worked on the Solaris 10, but causes a Segmenation Fault (core dumped) on the Solaris 11. Normally I'd say the segfault is being caused by trying to write to blank[35] when the blank[] array only goes up to blank[34] (it is initialized with 35 space characters), except this code worked on the Solaris 10.

Also, when I change the line to 'blank[34] = '\0';' on the new server, I still get a segfault core dump.

When I change blank to a normal array (and also modernize main), everything works fine, as I'd expect:

#include <stdio.h>

char blank[35];

int main(int argc,char **argv)
{

  int i;

  for (i=0; i<34; i++)
  {
   blank[i] = ' ';
  }

  blank[34] = '\0';
  printf("Success.\n");
  return 0;
}

What I really need to know is why this code ran okay on the old server, and what am I overlooking? I can change the code to use a normal array to make it run on the new server, but what sort of problems might that cause?


Solution

  • Are they using the exact same version of the C compiler and exact same flags?

    Older versions of the Studio compilers (/opt/SUNWspro/...) put constant strings in writable memory by default, unless you used the -features=conststrings flag to put them in read-only memory.

    Later versions of the Studio compilers made -features=conststrings the default and require -features=no%conststrings to make them writable again, as shown in the Studio 12.6 docs at https://docs.oracle.com/cd/E77782_01/html/E77788/bjapr.html#OSSCGbjaqo.

    This is similar to what gcc has done with the equivalent flag -fwritable-strings which was on by default in the oldest versions, then was turned off by default in several releases, before being removed in gcc 4.0, making constant strings always in read-only memory.