environ (and NXArgc, NXArgv) are dead-stripped and unusable; x86 program crashes

Originator:mark
Number:rdar://12008589 Date Originated:2012-08-01
Status:Duplicate/6435909 Resolved:
Product:Developer Tools Product Version:4.4 4F250 ld64-133.3
Classification:Crash/Hang/Data Loss Reproducible:Always
 
01-Aug-2012 04:21 PM Mark Mentovai:
Summary:

I should be able to access the C standard “environ” variable documented in “man environ” and http://pubs.opengroup.org/onlinepubs/9699919799/functions/environ.html simply by declaring it:

extern char** environ;

When I attempt to do so under certain conditions, attempts to access environ at runtime cause the program to crash. environ has value 0, and dereferencing it results in a crash. Similarly, NXArgc and NXArgv also both have value 0, and dereferencing NXArgv causes a crash.

I have found that this problem occurs in a 32-bit x86 program built with the SDK set to 10.6 or 10.7, the deployment target set to 10.6 or 10.7, and dead code stripping enabled. This does not happen in 64-bit programs, or with the deployment target or SDK set to 10.5 or 10.8.

Under these conditions, the linker is not placing environ in the output and is in fact removing the entire __DATA,__program_vars section that is intended to contain these variables.

Steps to Reproduce:

This simple test program:

--
#include <stdio.h>

extern char** environ;

int main(int argc, char* argv[]) {
  for (char** variable = environ; *variable; ++variable) {
    printf("%s\n", *variable);
  }
  return 0;
}
--

compiled with

clang -Wall -arch i386 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk
 -mmacosx-version-min=10.6.0 t.c -o t -dead_strip

when run, should print the contents of the environment, but instead crashes.

Expected Results:

environ should be accessible. The contents of the environment should be printed when running the test program above.

Actual Results:

environ is not usable. The program crashes with SIGBUS. “environ” has value 0 (NULL), so the attempt to dereference it results in a crash.

Regression:

Yes, this is a regression. This works correctly in Xcode 3.2.

Notes:

I am attaching* this sample test program as an Xcode project. To exhibit the bug, I have made the following changes to the default template for a command-line tool project at the project level:

ARCHS = $(ARCHS_STANDARD_32_BIT)
SDKROOT = macosx10.7
MACOSX_DEPLOYMENT_TARGET = 10.6
DEAD_CODE_STRIPPING = YES

I have made these changes for both Debug and Release modes, although I don’t normally enable dead code stripping for debug mode, because Xcode 4 makes it painful to run anything other than the Debug product from within the Xcode environment itself.

If you open the attached project and build it and run it (command-R), it will crash. The program is well-formed. It shouldn’t crash, it should simply print the contents of the environment.

* http://crbug.com/139902#c17

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!