24
24
#include < string.h>
25
25
#include < assert.h>
26
26
27
- #include < string>
28
-
29
27
/* *
30
28
* Equivalent to ScopedLocalRef, but for C_JNIEnv instead. (And slightly more powerful.)
31
29
*/
@@ -94,7 +92,8 @@ extern "C" int jniRegisterNativeMethods(C_JNIEnv* env, const char* className,
94
92
* be populated with the "binary" class name and, if present, the
95
93
* exception message.
96
94
*/
97
- static bool getExceptionSummary (C_JNIEnv* env, jthrowable exception , std::string& result) {
95
+ static bool logExceptionSummary (C_JNIEnv *env, jthrowable exception ,
96
+ const char * exceptionClassName) {
98
97
JNIEnv* e = reinterpret_cast <JNIEnv*>(env);
99
98
100
99
/* get the name of the exception's class */
@@ -107,16 +106,17 @@ static bool getExceptionSummary(C_JNIEnv* env, jthrowable exception, std::string
107
106
(jstring) (*env)->CallObjectMethod (e, exceptionClass.get (), classGetNameMethod));
108
107
if (classNameStr.get () == NULL ) {
109
108
(*env)->ExceptionClear (e);
110
- result = " <error getting class name>" ;
109
+ ALOGW (" Discarding pending exception (%s) to throw %s" , " <error getting class name>" ,
110
+ exceptionClassName);
111
111
return false ;
112
112
}
113
113
const char * classNameChars = (*env)->GetStringUTFChars (e, classNameStr.get (), NULL );
114
114
if (classNameChars == NULL ) {
115
115
(*env)->ExceptionClear (e);
116
- result = " <error getting class name UTF-8>" ;
116
+ ALOGW (" Discarding pending exception (%s) to throw %s" , " <error getting class name UTF-8>" ,
117
+ exceptionClassName);
117
118
return false ;
118
119
}
119
- result += classNameChars;
120
120
(*env)->ReleaseStringUTFChars (e, classNameStr.get (), classNameChars);
121
121
122
122
/* if the exception has a detail message, get that */
@@ -128,81 +128,23 @@ static bool getExceptionSummary(C_JNIEnv* env, jthrowable exception, std::string
128
128
return true ;
129
129
}
130
130
131
- result += " : " ;
132
-
133
131
const char * messageChars = (*env)->GetStringUTFChars (e, messageStr.get (), NULL );
134
132
if (messageChars != NULL ) {
135
- result += messageChars;
133
+ ALOGW (" Discarding pending exception (%s: %s) to throw %s" ,
134
+ classNameChars,
135
+ messageChars,
136
+ exceptionClassName);
136
137
(*env)->ReleaseStringUTFChars (e, messageStr.get (), messageChars);
137
138
} else {
138
- result += " <error getting message>" ;
139
+ ALOGW (" Discarding pending exception (%s: <error getting message>) to throw %s" ,
140
+ classNameChars,
141
+ exceptionClassName);
139
142
(*env)->ExceptionClear (e); // clear OOM
140
143
}
141
144
142
145
return true ;
143
146
}
144
147
145
- /*
146
- * Returns an exception (with stack trace) as a string.
147
- */
148
- static bool getStackTrace (C_JNIEnv* env, jthrowable exception , std::string& result) {
149
- JNIEnv* e = reinterpret_cast <JNIEnv*>(env);
150
-
151
- scoped_local_ref<jclass> stringWriterClass (env, findClass (env, " java/io/StringWriter" ));
152
- if (stringWriterClass.get () == NULL ) {
153
- return false ;
154
- }
155
-
156
- jmethodID stringWriterCtor = (*env)->GetMethodID (e, stringWriterClass.get (), " <init>" , " ()V" );
157
- jmethodID stringWriterToStringMethod =
158
- (*env)->GetMethodID (e, stringWriterClass.get (), " toString" , " ()Ljava/lang/String;" );
159
-
160
- scoped_local_ref<jclass> printWriterClass (env, findClass (env, " java/io/PrintWriter" ));
161
- if (printWriterClass.get () == NULL ) {
162
- return false ;
163
- }
164
-
165
- jmethodID printWriterCtor =
166
- (*env)->GetMethodID (e, printWriterClass.get (), " <init>" , " (Ljava/io/Writer;)V" );
167
-
168
- scoped_local_ref<jobject> stringWriter (env,
169
- (*env)->NewObject (e, stringWriterClass.get (), stringWriterCtor));
170
- if (stringWriter.get () == NULL ) {
171
- return false ;
172
- }
173
-
174
- jobject printWriter =
175
- (*env)->NewObject (e, printWriterClass.get (), printWriterCtor, stringWriter.get ());
176
- if (printWriter == NULL ) {
177
- return false ;
178
- }
179
-
180
- scoped_local_ref<jclass> exceptionClass (env, (*env)->GetObjectClass (e, exception )); // can't fail
181
- jmethodID printStackTraceMethod =
182
- (*env)->GetMethodID (e, exceptionClass.get (), " printStackTrace" , " (Ljava/io/PrintWriter;)V" );
183
- (*env)->CallVoidMethod (e, exception , printStackTraceMethod, printWriter);
184
-
185
- if ((*env)->ExceptionCheck (e)) {
186
- return false ;
187
- }
188
-
189
- scoped_local_ref<jstring> messageStr (env,
190
- (jstring) (*env)->CallObjectMethod (e, stringWriter.get (), stringWriterToStringMethod));
191
- if (messageStr.get () == NULL ) {
192
- return false ;
193
- }
194
-
195
- const char * utfChars = (*env)->GetStringUTFChars (e, messageStr.get (), NULL );
196
- if (utfChars == NULL ) {
197
- return false ;
198
- }
199
-
200
- result = utfChars;
201
-
202
- (*env)->ReleaseStringUTFChars (e, messageStr.get (), utfChars);
203
- return true ;
204
- }
205
-
206
148
extern " C" int jniThrowException (C_JNIEnv* env, const char * className, const char * msg) {
207
149
JNIEnv* e = reinterpret_cast <JNIEnv*>(env);
208
150
@@ -212,9 +154,7 @@ extern "C" int jniThrowException(C_JNIEnv* env, const char* className, const cha
212
154
(*env)->ExceptionClear (e);
213
155
214
156
if (exception .get () != NULL ) {
215
- std::string text;
216
- getExceptionSummary (env, exception .get (), text);
217
- ALOGW (" Discarding pending exception (%s) to throw %s" , text.c_str (), className);
157
+ logExceptionSummary (env, exception .get (), className);
218
158
}
219
159
}
220
160
@@ -254,39 +194,6 @@ int jniThrowIOException(C_JNIEnv* env, int errnum) {
254
194
return jniThrowException (env, " java/io/IOException" , message);
255
195
}
256
196
257
- static std::string jniGetStackTrace (C_JNIEnv* env, jthrowable exception ) {
258
- JNIEnv* e = reinterpret_cast <JNIEnv*>(env);
259
-
260
- scoped_local_ref<jthrowable> currentException (env, (*env)->ExceptionOccurred (e));
261
- if (exception == NULL ) {
262
- exception = currentException.get ();
263
- if (exception == NULL ) {
264
- return " <no pending exception>" ;
265
- }
266
- }
267
-
268
- if (currentException.get () != NULL ) {
269
- (*env)->ExceptionClear (e);
270
- }
271
-
272
- std::string trace;
273
- if (!getStackTrace (env, exception , trace)) {
274
- (*env)->ExceptionClear (e);
275
- getExceptionSummary (env, exception , trace);
276
- }
277
-
278
- if (currentException.get () != NULL ) {
279
- (*env)->Throw (e, currentException.get ()); // rethrow
280
- }
281
-
282
- return trace;
283
- }
284
-
285
- void jniLogException (C_JNIEnv* env, int priority, const char * tag, jthrowable exception ) {
286
- std::string trace (jniGetStackTrace (env, exception ));
287
- __android_log_write (priority, tag, trace.c_str ());
288
- }
289
-
290
197
const char * jniStrError (int errnum, char * buf, size_t buflen) {
291
198
#if __GLIBC__
292
199
// Note: glibc has a nonstandard strerror_r that returns char* rather than POSIX's int.
@@ -303,3 +210,8 @@ const char* jniStrError(int errnum, char* buf, size_t buflen) {
303
210
return buf;
304
211
#endif
305
212
}
213
+
214
+ void * operator new (size_t size) { return malloc (size); }
215
+ void * operator new [] (size_t size) { return malloc (size); }
216
+ void operator delete (void * pointer) { free (pointer); }
217
+ void operator delete [] (void * pointer) { free (pointer); }
0 commit comments