+__private_extern__ char *__crashreporter_info__ = NULL;
+
+OBJC_EXPORT void (*_error)(id, const char *, va_list);
+
+static void _objc_trap(void) __attribute__((noreturn));
+
+// Add "message" to any forthcoming crash log.
+static void _objc_crashlog(const char *message)
+{
+ char *newmsg;
+
+ if (!__crashreporter_info__) {
+ newmsg = strdup(message);
+ } else {
+ asprintf(&newmsg, "%s\n%s", __crashreporter_info__, message);
+ }
+
+ if (newmsg) {
+ // Strip trailing newline
+ char *c = &newmsg[strlen(newmsg)-1];
+ if (*c == '\n') *c = '\0';
+
+ if (__crashreporter_info__) free(__crashreporter_info__);
+ __crashreporter_info__ = newmsg;
+ }
+}
+
+// Print "message" to the console.
+static void _objc_syslog(const char *message)
+{
+ if (fcntl(STDERR_FILENO, F_GETFL, 0) != -1) {
+ // stderr is open - use it
+ write(STDERR_FILENO, message, strlen(message));
+ if (message[strlen(message)-1] != '\n') {
+ write(STDERR_FILENO, "\n", 1);
+ }
+ } else {
+ syslog(LOG_ERR, "%s", message);
+ }
+}
+/*
+ * this routine handles errors that involve an object (or class).