| Index: runtime/bin/process_macos.cc | 
| diff --git a/runtime/bin/process_macos.cc b/runtime/bin/process_macos.cc | 
| index 8f2891fcd427ad4a0ddc0a95e4819470199fe539..bf81a8c31f6759ea6b61de315dd7df8772a5e504 100644 | 
| --- a/runtime/bin/process_macos.cc | 
| +++ b/runtime/bin/process_macos.cc | 
| @@ -27,8 +27,6 @@ | 
| #include "platform/signal_blocker.h" | 
|  | 
|  | 
| -extern char** environ; | 
| - | 
|  | 
| namespace dart { | 
| namespace bin { | 
| @@ -157,7 +155,7 @@ class ExitCodeHandler { | 
|  | 
| // Fork to wake up waitpid. | 
| if (TEMP_FAILURE_RETRY(fork()) == 0) { | 
| -      _exit(0); | 
| +      exit(0); | 
| } | 
|  | 
| monitor_->Notify(); | 
| @@ -425,7 +423,7 @@ class ProcessStarter { | 
| int bytes_read = FDUtils::ReadFromBlocking(read_in_[0], &msg, sizeof(msg)); | 
| if (bytes_read != sizeof(msg)) { | 
| perror("Failed receiving notification message"); | 
| -      _exit(1); | 
| +      exit(1); | 
| } | 
| if (mode_ == kNormal) { | 
| ExecProcess(); | 
| @@ -516,13 +514,13 @@ class ProcessStarter { | 
| execvp(path_, const_cast<char* const*>(program_arguments_))); | 
| ReportChildError(); | 
| } else { | 
| -          // Exit the intermediate process. | 
| -          _exit(0); | 
| +          // Exit the intermeiate process. | 
| +          exit(0); | 
| } | 
| } | 
| } else { | 
| -      // Exit the intermediate process. | 
| -      _exit(0); | 
| +      // Exit the intermeiate process. | 
| +      exit(0); | 
| } | 
| } | 
|  | 
| @@ -554,7 +552,7 @@ class ProcessStarter { | 
| FDUtils::ReadFromBlocking( | 
| exec_control_[0], &child_errno, sizeof(child_errno)); | 
| if (bytes_read == sizeof(child_errno)) { | 
| -      SetOSErrorMessage(child_errno); | 
| +      ReadChildError(); | 
| return child_errno; | 
| } else if (bytes_read == -1) { | 
| return errno; | 
| @@ -578,7 +576,7 @@ class ProcessStarter { | 
| } else if (bytes_read == 2 * sizeof(int)) { | 
| *pid = result[0]; | 
| child_errno = result[1]; | 
| -      SetOSErrorMessage(child_errno); | 
| +      ReadChildError(); | 
| return child_errno; | 
| } else if (bytes_read == -1) { | 
| return errno; | 
| @@ -660,17 +658,29 @@ class ProcessStarter { | 
|  | 
|  | 
| void SetChildOsErrorMessage() { | 
| -    SetOSErrorMessage(errno); | 
| +    const int kBufferSize = 1024; | 
| +    char error_message[kBufferSize]; | 
| +    strerror_r(errno, error_message, kBufferSize); | 
| +    *os_error_message_ = strdup(error_message); | 
| } | 
|  | 
|  | 
| void ReportChildError() { | 
| -    // In the case of failure in the child process write the errno to the exec | 
| -    // control pipe and exit. | 
| +    // In the case of failure in the child process write the errno and | 
| +    // the OS error message to the exec control pipe and exit. | 
| int child_errno = errno; | 
| -    FDUtils::WriteToBlocking( | 
| -        exec_control_[1], &child_errno, sizeof(child_errno)); | 
| -    _exit(1); | 
| +    const int kBufferSize = 1024; | 
| +    char os_error_message[kBufferSize]; | 
| +    strerror_r(errno, os_error_message, kBufferSize); | 
| +    int bytes_written = | 
| +        FDUtils::WriteToBlocking( | 
| +            exec_control_[1], &child_errno, sizeof(child_errno)); | 
| +    if (bytes_written == sizeof(child_errno)) { | 
| +      FDUtils::WriteToBlocking( | 
| +          exec_control_[1], os_error_message, strlen(os_error_message) + 1); | 
| +    } | 
| +    VOID_TEMP_FAILURE_RETRY(close(exec_control_[1])); | 
| +    exit(1); | 
| } | 
|  | 
|  | 
| @@ -684,11 +694,17 @@ class ProcessStarter { | 
| } | 
|  | 
|  | 
| -  void SetOSErrorMessage(int child_errno) { | 
| -    const int kBufferSize = 1024; | 
| -    char error_message[kBufferSize]; | 
| -    strerror_r(child_errno, error_message, kBufferSize); | 
| -    *os_error_message_ = strdup(error_message); | 
| +  void ReadChildError() { | 
| +    const int kMaxMessageSize = 256; | 
| +    char* message = static_cast<char*>(malloc(kMaxMessageSize)); | 
| +    if (message != NULL) { | 
| +      FDUtils::ReadFromBlocking(exec_control_[0], message, kMaxMessageSize); | 
| +      message[kMaxMessageSize - 1] = '\0'; | 
| +      *os_error_message_ = message; | 
| +    } else { | 
| +      // Could not get error message. It will be NULL. | 
| +      ASSERT(*os_error_message_ == NULL); | 
| +    } | 
| } | 
|  | 
|  | 
|  |