Commit 72faffbc authored by David Crawshaw's avatar David Crawshaw

runtime/cgo: replace fprintf(stderr, ...) with fatalf(...) for linux/android

Both stdout and stderr are sent to /dev/null in android
apps. Introducing fatalf allows android to implement its
own copy that sends fatal errors to __android_log_print.

LGTM=minux, dave
R=minux, dave
CC=golang-codereviews
https://golang.org/cl/108400045
parent 822b2cbb
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
#include <stdarg.h>
#include <android/log.h>
#include "libcgo.h"
void
fatalf(const char* format, ...)
{
va_list ap;
// Write to both stderr and logcat.
//
// When running from an .apk, /dev/stderr and /dev/stdout
// redirect to /dev/null. And when running a test binary
// via adb shell, it's easy to miss logcat.
fprintf(stderr, "runtime/cgo: ");
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
fprintf(stderr, "\n");
va_start(ap, format);
__android_log_vprint(ANDROID_LOG_FATAL, "runtime/cgo", format, ap);
va_end(ap);
abort();
}
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
#include <android/log.h>
#include <pthread.h> #include <pthread.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
...@@ -28,9 +27,7 @@ inittls(void **tlsg, void **tlsbase) ...@@ -28,9 +27,7 @@ inittls(void **tlsg, void **tlsbase)
err = pthread_key_create(&k, nil); err = pthread_key_create(&k, nil);
if(err != 0) { if(err != 0) {
fprintf(stderr, "runtime/cgo: pthread_key_create failed: %d\n", err); fatalf("pthread_key_create failed: %d", err);
__android_log_print(ANDROID_LOG_FATAL, "runtime/cgo", "pthread_key_create failed: %d", err);
abort();
} }
pthread_setspecific(k, (void*)magic1); pthread_setspecific(k, (void*)magic1);
for (i=0; i<PTHREAD_KEYS_MAX; i++) { for (i=0; i<PTHREAD_KEYS_MAX; i++) {
...@@ -40,9 +37,7 @@ inittls(void **tlsg, void **tlsbase) ...@@ -40,9 +37,7 @@ inittls(void **tlsg, void **tlsbase)
return; return;
} }
} }
fprintf(stderr, "runtime/cgo: could not find pthread key\n"); fatalf("could not find pthread key");
__android_log_print(ANDROID_LOG_FATAL, "runtime/cgo", "could not find pthread key");
abort();
} }
void (*x_cgo_inittls)(void **tlsg, void **tlsbase) = inittls; void (*x_cgo_inittls)(void **tlsg, void **tlsbase) = inittls;
// Copyright 2014 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build !android,linux
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "libcgo.h"
void
fatalf(const char* format, ...)
{
va_list ap;
fprintf(stderr, "runtime/cgo: ");
va_start(ap, format);
vfprintf(stderr, format, ap);
va_end(ap);
fprintf(stderr, "\n");
abort();
}
...@@ -49,8 +49,7 @@ _cgo_sys_thread_start(ThreadStart *ts) ...@@ -49,8 +49,7 @@ _cgo_sys_thread_start(ThreadStart *ts)
pthread_sigmask(SIG_SETMASK, &oset, nil); pthread_sigmask(SIG_SETMASK, &oset, nil);
if (err != 0) { if (err != 0) {
fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err)); fatalf("pthread_create failed: %s", strerror(err));
abort();
} }
} }
......
...@@ -44,8 +44,7 @@ _cgo_sys_thread_start(ThreadStart *ts) ...@@ -44,8 +44,7 @@ _cgo_sys_thread_start(ThreadStart *ts)
pthread_sigmask(SIG_SETMASK, &oset, nil); pthread_sigmask(SIG_SETMASK, &oset, nil);
if (err != 0) { if (err != 0) {
fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err)); fatalf("pthread_create failed: %s", strerror(err));
abort();
} }
} }
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
static void *threadentry(void*); static void *threadentry(void*);
void (*x_cgo_inittls)(void **tlsg, void **tlsbase);
void (*setg_gcc)(void*); void (*setg_gcc)(void*);
void void
...@@ -36,8 +37,7 @@ _cgo_sys_thread_start(ThreadStart *ts) ...@@ -36,8 +37,7 @@ _cgo_sys_thread_start(ThreadStart *ts)
pthread_sigmask(SIG_SETMASK, &oset, nil); pthread_sigmask(SIG_SETMASK, &oset, nil);
if (err != 0) { if (err != 0) {
fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err)); fatalf("pthread_create failed: %s", strerror(err));
abort();
} }
} }
...@@ -62,8 +62,6 @@ threadentry(void *v) ...@@ -62,8 +62,6 @@ threadentry(void *v)
return nil; return nil;
} }
void (*x_cgo_inittls)(void **tlsg, void **tlsbase);
void void
x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase) x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
{ {
......
...@@ -58,3 +58,8 @@ void crosscall_amd64(void (*fn)(void)); ...@@ -58,3 +58,8 @@ void crosscall_amd64(void (*fn)(void));
* Call fn in the 8c world. * Call fn in the 8c world.
*/ */
void crosscall_386(void (*fn)(void)); void crosscall_386(void (*fn)(void));
/*
* Prints error then calls abort. For linux and android.
*/
void fatalf(const char* format, ...);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment