Skip to content
This repository was archived by the owner on Mar 9, 2022. It is now read-only.

Commit 53c57cb

Browse files
committed
log messages sent to stdout/stderr before the VM is booted
Change-Id: I604135c8ccd414cbd0500254a0500182a58259c4 Reviewed-on: http://review.couchbase.org/10702 Tested-by: Marty Schoch <[email protected]> Reviewed-by: Marty Schoch <[email protected]>
1 parent bcae862 commit 53c57cb

File tree

2 files changed

+163
-0
lines changed

2 files changed

+163
-0
lines changed

jni/com_couchbase_android_ErlangThread.cpp

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,89 @@
66

77
#include "android/log.h"
88

9+
#include "erl_printf.h"
10+
911
#define LOG_TAG "ErlangThread"
1012
#define LOGV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
1113
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
1214

15+
#define ALLOC(X) malloc(X)
16+
#define REALLOC(X,Y) realloc(X,Y)
17+
#define FREE(X) free(X)
18+
19+
#define ANDROID_VPRINTF_BUF_INC_SIZE 1024
20+
21+
int (*ref_erts_vdsprintf)(erts_dsprintf_buf_t *dsbufp, const char *format, va_list arglist) = NULL;
22+
23+
static erts_dsprintf_buf_t * grow_android_vprintf_buf(erts_dsprintf_buf_t *dsbufp, size_t need)
24+
{
25+
char *buf;
26+
size_t size;
27+
28+
if (!dsbufp->str) {
29+
size = (((need + ANDROID_VPRINTF_BUF_INC_SIZE - 1)
30+
/ ANDROID_VPRINTF_BUF_INC_SIZE)
31+
* ANDROID_VPRINTF_BUF_INC_SIZE);
32+
buf = (char *) ALLOC(size * sizeof(char));
33+
}
34+
else {
35+
size_t free_size = dsbufp->size - dsbufp->str_len;
36+
37+
if (need <= free_size)
38+
return dsbufp;
39+
40+
size = need - free_size + ANDROID_VPRINTF_BUF_INC_SIZE;
41+
size = (((size + ANDROID_VPRINTF_BUF_INC_SIZE - 1)
42+
/ ANDROID_VPRINTF_BUF_INC_SIZE)
43+
* ANDROID_VPRINTF_BUF_INC_SIZE);
44+
size += dsbufp->size;
45+
buf = (char *) REALLOC((void *) dsbufp->str,
46+
size * sizeof(char));
47+
}
48+
if (!buf)
49+
return NULL;
50+
if (buf != dsbufp->str)
51+
dsbufp->str = buf;
52+
dsbufp->size = size;
53+
return dsbufp;
54+
}
55+
56+
static int android_stdout_vprintf(char *format, va_list arg_list) {
57+
int res,i;
58+
erts_dsprintf_buf_t dsbuf = ERTS_DSPRINTF_BUF_INITER(grow_android_vprintf_buf);
59+
res = ref_erts_vdsprintf(&dsbuf, format, arg_list);
60+
if (res >= 0) {
61+
char *tmp = (char*)ALLOC((dsbuf.str_len + 1)*sizeof(char));
62+
for (i=0;i<dsbuf.str_len;++i) {
63+
tmp[i] = dsbuf.str[i];
64+
}
65+
tmp[dsbuf.str_len] = NULL;
66+
LOGV(tmp);
67+
FREE(tmp);
68+
}
69+
if (dsbuf.str)
70+
FREE((void *) dsbuf.str);
71+
return res;
72+
}
73+
74+
static int android_stderr_vprintf(char *format, va_list arg_list) {
75+
int res,i;
76+
erts_dsprintf_buf_t dsbuf = ERTS_DSPRINTF_BUF_INITER(grow_android_vprintf_buf);
77+
res = ref_erts_vdsprintf(&dsbuf, format, arg_list);
78+
if (res >= 0) {
79+
char *tmp = (char*)ALLOC((dsbuf.str_len + 1)*sizeof(char));
80+
for (i=0;i<dsbuf.str_len;++i) {
81+
tmp[i] = dsbuf.str[i];
82+
}
83+
tmp[dsbuf.str_len] = NULL;
84+
LOGE(tmp);
85+
FREE(tmp);
86+
}
87+
if (dsbuf.str)
88+
FREE((void *) dsbuf.str);
89+
return res;
90+
}
91+
1392
JavaVM *jvm;
1493
jclass ErlangThread;
1594
jmethodID ErlMessageMethod;
@@ -20,6 +99,8 @@ JNIEXPORT void JNICALL Java_com_couchbase_android_ErlangThread_start_1erlang
2099
int i, argc;
21100
char ** argv;
22101
void (*erl_start)(int, char**) = NULL;
102+
int (**erts_printf_stdout_func)(char *, va_list) = NULL;
103+
int (**erts_printf_stderr_func)(char *, va_list) = NULL;
23104

24105
const char *sopath = env->GetStringUTFChars(j_sopath, &iscopy);
25106
const char *bindir = env->GetStringUTFChars(j_bindir, &iscopy);
@@ -35,6 +116,31 @@ JNIEXPORT void JNICALL Java_com_couchbase_android_ErlangThread_start_1erlang
35116
LOGE("Failed to find erl_start: %s", dlerror());
36117
goto cleanup;
37118
}
119+
120+
*(void **)(&erts_printf_stdout_func) = dlsym(handle, "erts_printf_stdout_func");
121+
if(!erts_printf_stdout_func) {
122+
LOGE("Failed to find erts_printf_stdout_func: %s", dlerror());
123+
goto cleanup;
124+
}
125+
else {
126+
*erts_printf_stdout_func = android_stdout_vprintf;
127+
}
128+
129+
*(void **)(&erts_printf_stderr_func) = dlsym(handle, "erts_printf_stderr_func");
130+
if(!erts_printf_stderr_func) {
131+
LOGE("Failed to find erts_printf_stderr_func: %s", dlerror());
132+
goto cleanup;
133+
}
134+
else {
135+
*erts_printf_stderr_func = android_stderr_vprintf;
136+
}
137+
138+
*(void **)(&ref_erts_vdsprintf) = dlsym(handle, "erts_vdsprintf");
139+
if(!erts_vdsprintf) {
140+
LOGE("Failed to find erts_vdsprintf: %s", dlerror());
141+
goto cleanup;
142+
}
143+
38144
argc = env->GetArrayLength(j_args);
39145
argv = (char**) malloc(sizeof(char*) * argc);
40146

jni/erl_printf.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* %CopyrightBegin%
3+
*
4+
* Copyright Ericsson AB 2005-2009. All Rights Reserved.
5+
*
6+
* The contents of this file are subject to the Erlang Public License,
7+
* Version 1.1, (the "License"); you may not use this file except in
8+
* compliance with the License. You should have received a copy of the
9+
* Erlang Public License along with this software. If not, it can be
10+
* retrieved online at http://www.erlang.org/.
11+
*
12+
* Software distributed under the License is distributed on an "AS IS"
13+
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
14+
* the License for the specific language governing rights and limitations
15+
* under the License.
16+
*
17+
* %CopyrightEnd%
18+
*/
19+
20+
#ifndef ERL_PRINTF_H_
21+
#define ERL_PRINTF_H_
22+
#include <stdio.h>
23+
#include <stdarg.h>
24+
25+
extern int (*erts_printf_stdout_func)(char *, va_list);
26+
extern int (*erts_printf_stderr_func)(char *, va_list);
27+
extern int erts_printf_add_cr_to_stdout;
28+
extern int erts_printf_add_cr_to_stderr;
29+
extern int (*erts_printf_block_fpe)(void);
30+
extern void (*erts_printf_unblock_fpe)(int);
31+
32+
typedef struct erts_dsprintf_buf_t_ erts_dsprintf_buf_t;
33+
34+
struct erts_dsprintf_buf_t_ {
35+
char *str;
36+
size_t str_len;
37+
size_t size;
38+
erts_dsprintf_buf_t *(*grow)(erts_dsprintf_buf_t *, size_t);
39+
};
40+
41+
#define ERTS_DSPRINTF_BUF_INITER(GFUNC) {NULL, 0, 0, (GFUNC)}
42+
43+
int erts_printf(const char *, ...);
44+
int erts_fprintf(FILE *, const char *, ...);
45+
int erts_fdprintf(int, const char *, ...);
46+
int erts_sprintf(char *, const char *, ...);
47+
int erts_snprintf(char *, size_t, const char *, ...);
48+
int erts_dsprintf(erts_dsprintf_buf_t *, const char *, ...);
49+
50+
int erts_vprintf(const char *, va_list);
51+
int erts_vfprintf(FILE *, const char *, va_list);
52+
int erts_vfdprintf(int, const char *, va_list);
53+
int erts_vsprintf(char *, const char *, va_list);
54+
int erts_vsnprintf(char *, size_t, const char *, va_list);
55+
int erts_vdsprintf(erts_dsprintf_buf_t *, const char *, va_list);
56+
57+
#endif /* #ifndef ERL_PRINTF_H_ */

0 commit comments

Comments
 (0)