const Object* resultObj = (const Object*) pResult->l;
if (resultObj == kInvalidIndirectRefObject) {
- LOGW("JNI WARNING: invalid reference returned from native code");
+ ALOGW("JNI WARNING: invalid reference returned from native code");
const Method* method = dvmGetCurrentJNIMethod();
char* desc = dexProtoCopyMethodDescriptor(&method->prototype);
- LOGW(" in %s.%s:%s", method->clazz->descriptor, method->name, desc);
+ ALOGW(" in %s.%s:%s", method->clazz->descriptor, method->name, desc);
free(desc);
abortMaybe();
return;
*/
ClassObject* declClazz = dvmFindClassNoInit(declType, method->clazz->classLoader);
if (declClazz == NULL) {
- LOGW("JNI WARNING: method declared to return '%s' returned '%s'",
+ ALOGW("JNI WARNING: method declared to return '%s' returned '%s'",
declType, objType);
- LOGW(" failed in %s.%s ('%s' not found)",
+ ALOGW(" failed in %s.%s ('%s' not found)",
method->clazz->descriptor, method->name, declType);
abortMaybe();
return;
}
if (!dvmInstanceof(objClazz, declClazz)) {
- LOGW("JNI WARNING: method declared to return '%s' returned '%s'",
+ ALOGW("JNI WARNING: method declared to return '%s' returned '%s'",
declType, objType);
- LOGW(" failed in %s.%s",
+ ALOGW(" failed in %s.%s",
method->clazz->descriptor, method->name);
abortMaybe();
return;
return ((JavaVMExt*) vm)->baseFuncTable;
}
-class ScopedJniThreadState {
+class ScopedCheckJniThreadState {
public:
- explicit ScopedJniThreadState(JNIEnv* env) {
+ explicit ScopedCheckJniThreadState(JNIEnv* env) {
dvmChangeStatus(NULL, THREAD_RUNNING);
}
- ~ScopedJniThreadState() {
+ ~ScopedCheckJniThreadState() {
dvmChangeStatus(NULL, THREAD_NATIVE);
}
private:
// Disallow copy and assignment.
- ScopedJniThreadState(const ScopedJniThreadState&);
- void operator=(const ScopedJniThreadState&);
+ ScopedCheckJniThreadState(const ScopedCheckJniThreadState&);
+ void operator=(const ScopedCheckJniThreadState&);
};
/*
*/
void checkClassName(const char* className) {
if (!dexIsValidClassName(className, false)) {
- LOGW("JNI WARNING: illegal class name '%s' (%s)", className, mFunctionName);
- LOGW(" (should be formed like 'dalvik/system/DexFile')");
- LOGW(" or '[Ldalvik/system/DexFile;' or '[[B')");
+ ALOGW("JNI WARNING: illegal class name '%s' (%s)", className, mFunctionName);
+ ALOGW(" (should be formed like 'dalvik/system/DexFile')");
+ ALOGW(" or '[Ldalvik/system/DexFile;' or '[[B')");
abortMaybe();
}
}
void checkFieldTypeForGet(jfieldID fid, const char* expectedSignature, bool isStatic) {
if (fid == NULL) {
- LOGW("JNI WARNING: null jfieldID");
+ ALOGW("JNI WARNING: null jfieldID (%s)", mFunctionName);
showLocation();
abortMaybe();
}
if (!printWarn && isStatic && !dvmIsStaticField(field)) {
if (isStatic) {
- LOGW("JNI WARNING: accessing non-static field %s as static", field->name);
+ ALOGW("JNI WARNING: accessing non-static field %s as static", field->name);
} else {
- LOGW("JNI WARNING: accessing static field %s as non-static", field->name);
+ ALOGW("JNI WARNING: accessing static field %s as non-static", field->name);
}
printWarn = true;
}
if (printWarn) {
- LOGW("JNI WARNING: %s for field '%s' of expected type %s, got %s",
+ ALOGW("JNI WARNING: %s for field '%s' of expected type %s, got %s",
mFunctionName, field->name, expectedSignature, actualSignature);
showLocation();
abortMaybe();
*/
void checkFieldTypeForSet(jobject jobj, jfieldID fieldID, PrimitiveType prim, bool isStatic) {
if (fieldID == NULL) {
- LOGW("JNI WARNING: null jfieldID");
+ ALOGW("JNI WARNING: null jfieldID (%s)", mFunctionName);
showLocation();
abortMaybe();
}
bool printWarn = false;
Field* field = (Field*) fieldID;
if ((field->signature[0] == 'L' || field->signature[0] == '[') && jobj != NULL) {
- ScopedJniThreadState ts(mEnv);
- Object* obj = dvmDecodeIndirectRef(mEnv, jobj);
+ ScopedCheckJniThreadState ts(mEnv);
+ Object* obj = dvmDecodeIndirectRef(self(), jobj);
/*
* If jobj is a weak global ref whose referent has been cleared,
* obj will be NULL. Otherwise, obj should always be non-NULL
* and valid.
*/
if (obj != NULL && !dvmIsHeapAddress(obj)) {
- LOGW("JNI WARNING: field operation on invalid %s reference (%p)",
- indirectRefKindName(jobj), jobj);
+ ALOGW("JNI WARNING: field operation (%s) on invalid %s reference (%p)",
+ mFunctionName, indirectRefKindName(jobj), jobj);
printWarn = true;
} else {
ClassObject* fieldClass = dvmFindLoadedClass(field->signature);
assert(objClass != NULL);
if (!dvmInstanceof(objClass, fieldClass)) {
- LOGW("JNI WARNING: set field '%s' expected type %s, got %s",
- field->name, field->signature, objClass->descriptor);
+ ALOGW("JNI WARNING: %s for field '%s' expected type %s, got %s",
+ mFunctionName, field->name, field->signature, objClass->descriptor);
printWarn = true;
}
}
} else if (dexGetPrimitiveTypeFromDescriptorChar(field->signature[0]) != prim) {
- LOGW("JNI WARNING: %s for field '%s' expected type %s, got %s",
+ ALOGW("JNI WARNING: %s for field '%s' expected type %s, got %s",
mFunctionName, field->name, field->signature, primitiveTypeToName(prim));
printWarn = true;
} else if (isStatic && !dvmIsStaticField(field)) {
if (isStatic) {
- LOGW("JNI WARNING: accessing non-static field %s as static", field->name);
+ ALOGW("JNI WARNING: %s for non-static field '%s'", mFunctionName, field->name);
} else {
- LOGW("JNI WARNING: accessing static field %s as non-static", field->name);
+ ALOGW("JNI WARNING: %s for static field '%s'", mFunctionName, field->name);
}
printWarn = true;
}
* Assumes "jobj" has already been validated.
*/
void checkInstanceFieldID(jobject jobj, jfieldID fieldID) {
- ScopedJniThreadState ts(mEnv);
+ ScopedCheckJniThreadState ts(mEnv);
- Object* obj = dvmDecodeIndirectRef(mEnv, jobj);
+ Object* obj = dvmDecodeIndirectRef(self(), jobj);
if (!dvmIsHeapAddress(obj)) {
- LOGW("JNI ERROR: field operation on invalid reference (%p)", jobj);
+ ALOGW("JNI ERROR: %s on invalid reference (%p)", mFunctionName, jobj);
dvmAbort();
}
clazz = clazz->super;
}
- LOGW("JNI WARNING: instance fieldID %p not valid for class %s",
- fieldID, obj->clazz->descriptor);
+ ALOGW("JNI WARNING: instance jfieldID %p not valid for class %s (%s)",
+ fieldID, obj->clazz->descriptor, mFunctionName);
showLocation();
abortMaybe();
}
*/
void checkNonNull(const void* ptr) {
if (ptr == NULL) {
- LOGW("JNI WARNING: invalid null pointer (%s)", mFunctionName);
+ ALOGW("JNI WARNING: invalid null pointer (%s)", mFunctionName);
abortMaybe();
}
}
bool printWarn = false;
if (*expectedType != method->shorty[0]) {
- LOGW("JNI WARNING: expected return type '%s'", expectedType);
+ ALOGW("JNI WARNING: %s expected return type '%s'", mFunctionName, expectedType);
printWarn = true;
} else if (isStatic && !dvmIsStaticMethod(method)) {
if (isStatic) {
- LOGW("JNI WARNING: calling non-static method with static call");
+ ALOGW("JNI WARNING: calling non-static method with static call %s", mFunctionName);
} else {
- LOGW("JNI WARNING: calling static method with non-static call");
+ ALOGW("JNI WARNING: calling static method with non-static call %s", mFunctionName);
}
printWarn = true;
}
if (printWarn) {
char* desc = dexProtoCopyMethodDescriptor(&method->prototype);
- LOGW(" calling %s.%s %s", method->clazz->descriptor, method->name, desc);
+ ALOGW(" calling %s.%s %s", method->clazz->descriptor, method->name, desc);
free(desc);
showLocation();
abortMaybe();
* Assumes "jclazz" has already been validated.
*/
void checkStaticFieldID(jclass jclazz, jfieldID fieldID) {
- ScopedJniThreadState ts(mEnv);
- ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(mEnv, jclazz);
+ ScopedCheckJniThreadState ts(mEnv);
+ ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(self(), jclazz);
StaticField* base = &clazz->sfields[0];
int fieldCount = clazz->sfieldCount;
if ((StaticField*) fieldID < base || (StaticField*) fieldID >= base + fieldCount) {
- LOGW("JNI WARNING: static fieldID %p not valid for class %s",
- fieldID, clazz->descriptor);
- LOGW(" base=%p count=%d", base, fieldCount);
+ ALOGW("JNI WARNING: static fieldID %p not valid for class %s (%s)",
+ fieldID, clazz->descriptor, mFunctionName);
+ ALOGW(" base=%p count=%d", base, fieldCount);
showLocation();
abortMaybe();
}
* Instances of "jclazz" must be instances of the method's declaring class.
*/
void checkStaticMethod(jclass jclazz, jmethodID methodID) {
- ScopedJniThreadState ts(mEnv);
+ ScopedCheckJniThreadState ts(mEnv);
- ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(mEnv, jclazz);
+ ClassObject* clazz = (ClassObject*) dvmDecodeIndirectRef(self(), jclazz);
const Method* method = (const Method*) methodID;
if (!dvmInstanceof(clazz, method->clazz)) {
- LOGW("JNI WARNING: can't call static %s.%s on class %s",
- method->clazz->descriptor, method->name, clazz->descriptor);
+ ALOGW("JNI WARNING: can't call static %s.%s on class %s (%s)",
+ method->clazz->descriptor, method->name, clazz->descriptor, mFunctionName);
showLocation();
// no abort?
}
* will be handled automatically by the instanceof check.)
*/
void checkVirtualMethod(jobject jobj, jmethodID methodID) {
- ScopedJniThreadState ts(mEnv);
+ ScopedCheckJniThreadState ts(mEnv);
- Object* obj = dvmDecodeIndirectRef(mEnv, jobj);
+ Object* obj = dvmDecodeIndirectRef(self(), jobj);
const Method* method = (const Method*) methodID;
if (!dvmInstanceof(obj->clazz, method->clazz)) {
- LOGW("JNI WARNING: can't call %s.%s on instance of %s",
- method->clazz->descriptor, method->name, obj->clazz->descriptor);
+ ALOGW("JNI WARNING: can't call %s.%s on instance of %s (%s)",
+ method->clazz->descriptor, method->name, obj->clazz->descriptor, mFunctionName);
showLocation();
abortMaybe();
}
* m - jmethodID
* p - void*
* r - jint (for release mode arguments)
+ * t - thread args (for AttachCurrentThread)
* u - const char* (modified UTF-8)
* z - jsize (for lengths; use i if negative values are okay)
* v - JavaVM*
msg += (b ? "JNI_TRUE" : "JNI_FALSE");
} else if (ch == 'c') { // jclass
jclass jc = va_arg(ap, jclass);
- Object* c = dvmDecodeIndirectRef(mEnv, jc);
+ Object* c = dvmDecodeIndirectRef(self(), jc);
if (c == NULL) {
msg += "NULL";
} else if (c == kInvalidIndirectRefObject || !dvmIsHeapAddress(c)) {
if (!entry) {
StringAppendF(&msg, " (%p)", mid);
}
- } else if (ch == 'p') { // void* ("pointer")
+ } else if (ch == 'p' || ch == 't') { // void* ("pointer" or "thread args")
void* p = va_arg(ap, void*);
if (p == NULL) {
msg += "NULL";
} else if (ch == '.') {
msg += "...";
} else {
- LOGE("unknown trace format specifier %c", ch);
+ ALOGE("unknown trace format specifier %c", ch);
dvmAbort();
}
if (*fmt) {
if (entry) {
if (mHasMethod) {
std::string methodName(dvmHumanReadableMethod(method, false));
- LOGI("JNI: %s -> %s(%s)", methodName.c_str(), mFunctionName, msg.c_str());
+ ALOGI("JNI: %s -> %s(%s)", methodName.c_str(), mFunctionName, msg.c_str());
mIndent = methodName.size() + 1;
} else {
- LOGI("JNI: -> %s(%s)", mFunctionName, msg.c_str());
+ ALOGI("JNI: -> %s(%s)", mFunctionName, msg.c_str());
mIndent = 0;
}
} else {
- LOGI("JNI: %*s<- %s returned %s", mIndent, "", mFunctionName, msg.c_str());
+ ALOGI("JNI: %*s<- %s returned %s", mIndent, "", mFunctionName, msg.c_str());
}
}
checkReleaseMode(va_arg(ap, jint));
} else if (ch == 's') {
checkString(va_arg(ap, jstring));
+ } else if (ch == 't') {
+ checkThreadArgs(va_arg(ap, void*));
} else if (ch == 'u') {
if ((mFlags & kFlag_Release) != 0) {
checkNonNull(va_arg(ap, const char*));
va_arg(ap, long); // Skip this argument.
} else if (ch == '.') {
} else {
- LOGE("unknown check format specifier %c", ch);
+ ALOGE("unknown check format specifier %c", ch);
dvmAbort();
}
}
}
}
+ // Only safe after checkThread returns.
+ Thread* self() {
+ return ((JNIEnvExt*) mEnv)->self;
+ }
+
private:
JNIEnv* mEnv;
const char* mFunctionName;
*/
void checkArray(jarray jarr) {
if (jarr == NULL) {
- LOGW("JNI WARNING: received null array");
+ ALOGW("JNI WARNING: %s received null array", mFunctionName);
showLocation();
abortMaybe();
return;
}
- ScopedJniThreadState ts(mEnv);
+ ScopedCheckJniThreadState ts(mEnv);
bool printWarn = false;
- Object* obj = dvmDecodeIndirectRef(mEnv, jarr);
+ Object* obj = dvmDecodeIndirectRef(self(), jarr);
if (!dvmIsHeapAddress(obj)) {
- LOGW("JNI WARNING: jarray is an invalid %s reference (%p)",
- indirectRefKindName(jarr), jarr);
+ ALOGW("JNI WARNING: %s: jarray is an invalid %s reference (%p)",
+ mFunctionName, indirectRefKindName(jarr), jarr);
printWarn = true;
} else if (obj->clazz->descriptor[0] != '[') {
- LOGW("JNI WARNING: jarray arg has wrong type (expected array, got %s)",
- obj->clazz->descriptor);
+ ALOGW("JNI WARNING: %s: jarray arg has wrong type (expected array, got %s)",
+ mFunctionName, obj->clazz->descriptor);
printWarn = true;
}
void checkLengthPositive(jsize length) {
if (length < 0) {
- LOGW("JNI WARNING: negative jsize (%s)", mFunctionName);
+ ALOGW("JNI WARNING: negative jsize (%s)", mFunctionName);
abortMaybe();
}
}
return;
}
- ScopedJniThreadState ts(mEnv);
+ ScopedCheckJniThreadState ts(mEnv);
bool printWarn = false;
- if (dvmGetJNIRefType(mEnv, jobj) == JNIInvalidRefType) {
- LOGW("JNI WARNING: %p is not a valid JNI reference", jobj);
+ if (dvmGetJNIRefType(self(), jobj) == JNIInvalidRefType) {
+ ALOGW("JNI WARNING: %p is not a valid JNI reference (%s)", jobj, mFunctionName);
printWarn = true;
} else {
- Object* obj = dvmDecodeIndirectRef(mEnv, jobj);
+ Object* obj = dvmDecodeIndirectRef(self(), jobj);
if (obj == kInvalidIndirectRefObject) {
- LOGW("JNI WARNING: native code passing in invalid reference %p", jobj);
+ ALOGW("JNI WARNING: native code passing in invalid reference %p (%s)",
+ jobj, mFunctionName);
printWarn = true;
} else if (obj != NULL && !dvmIsHeapAddress(obj)) {
// TODO: when we remove workAroundAppJniBugs, this should be impossible.
- LOGW("JNI WARNING: native code passing in reference to invalid object %p %p",
- jobj, obj);
+ ALOGW("JNI WARNING: native code passing in reference to invalid object %p %p (%s)",
+ jobj, obj, mFunctionName);
printWarn = true;
}
}
*/
void checkReleaseMode(jint mode) {
if (mode != 0 && mode != JNI_COMMIT && mode != JNI_ABORT) {
- LOGW("JNI WARNING: bad value for mode (%d) (%s)", mode, mFunctionName);
+ ALOGW("JNI WARNING: bad value for mode (%d) (%s)", mode, mFunctionName);
abortMaybe();
}
}
checkInstance(s, gDvm.classJavaLangString, "jstring");
}
+ void checkThreadArgs(void* thread_args) {
+ JavaVMAttachArgs* args = static_cast<JavaVMAttachArgs*>(thread_args);
+ if (args != NULL && args->version < JNI_VERSION_1_2) {
+ ALOGW("JNI WARNING: bad value for JNI version (%d) (%s)", args->version, mFunctionName);
+ abortMaybe();
+ }
+ }
+
void checkThread(int flags) {
// Get the *correct* JNIEnv by going through our TLS pointer.
JNIEnvExt* threadEnv = dvmGetJNIEnvForThread();
*/
bool printWarn = false;
if (threadEnv == NULL) {
- LOGE("JNI ERROR: non-VM thread making JNI calls");
+ ALOGE("JNI ERROR: non-VM thread making JNI call (%s)", mFunctionName);
// don't set printWarn -- it'll try to call showLocation()
dvmAbort();
} else if ((JNIEnvExt*) mEnv != threadEnv) {
if (dvmThreadSelf()->threadId != threadEnv->envThreadId) {
- LOGE("JNI: threadEnv != thread->env?");
+ ALOGE("JNI: threadEnv != thread->env? (%s)", mFunctionName);
dvmAbort();
}
- LOGW("JNI WARNING: threadid=%d using env from threadid=%d",
- threadEnv->envThreadId, ((JNIEnvExt*) mEnv)->envThreadId);
+ ALOGW("JNI WARNING: threadid=%d using env from threadid=%d (%s)",
+ threadEnv->envThreadId, ((JNIEnvExt*) mEnv)->envThreadId, mFunctionName);
printWarn = true;
// If we're keeping broken code limping along, we need to suppress the abort...
//dvmThrowRuntimeException("invalid use of JNI env ptr");
} else if (((JNIEnvExt*) mEnv)->self != dvmThreadSelf()) {
/* correct JNIEnv*; make sure the "self" pointer is correct */
- LOGE("JNI ERROR: env->self != thread-self (%p vs. %p)",
- ((JNIEnvExt*) mEnv)->self, dvmThreadSelf());
+ ALOGE("JNI ERROR: env->self != thread-self (%p vs. %p) (%s)",
+ ((JNIEnvExt*) mEnv)->self, dvmThreadSelf(), mFunctionName);
dvmAbort();
}
break;
case kFlag_CritBad: // not okay to call
if (threadEnv->critical) {
- LOGW("JNI WARNING: threadid=%d using JNI after critical get",
- threadEnv->envThreadId);
+ ALOGW("JNI WARNING: threadid=%d using JNI after critical get (%s)",
+ threadEnv->envThreadId, mFunctionName);
printWarn = true;
}
break;
case kFlag_CritRelease: // this is a "release" call
threadEnv->critical--;
if (threadEnv->critical < 0) {
- LOGW("JNI WARNING: threadid=%d called too many crit releases",
- threadEnv->envThreadId);
+ ALOGW("JNI WARNING: threadid=%d called too many critical releases (%s)",
+ threadEnv->envThreadId, mFunctionName);
printWarn = true;
}
break;
*/
bool printException = false;
if ((flags & kFlag_ExcepOkay) == 0 && dvmCheckException(dvmThreadSelf())) {
- LOGW("JNI WARNING: JNI method called with exception pending");
+ ALOGW("JNI WARNING: JNI function %s called with exception pending", mFunctionName);
printWarn = true;
printException = true;
}
showLocation();
}
if (printException) {
- LOGW("Pending exception is:");
+ ALOGW("Pending exception is:");
dvmLogExceptionStackTrace();
}
if (printWarn) {
void checkUtfString(const char* bytes, bool nullable) {
if (bytes == NULL) {
if (!nullable) {
- LOGW("JNI WARNING: non-nullable const char* was NULL");
+ ALOGW("JNI WARNING: non-nullable const char* was NULL (%s)", mFunctionName);
showLocation();
abortMaybe();
}
const char* errorKind = NULL;
u1 utf8 = checkUtfBytes(bytes, &errorKind);
if (errorKind != NULL) {
- LOGW("JNI WARNING: input is not valid Modified UTF-8: illegal %s byte %#x", errorKind, utf8);
- LOGW(" string: '%s'", bytes);
+ ALOGW("JNI WARNING: %s input is not valid Modified UTF-8: illegal %s byte %#x",
+ mFunctionName, errorKind, utf8);
+ ALOGW(" string: '%s'", bytes);
showLocation();
abortMaybe();
}
*/
void checkInstance(jobject jobj, ClassObject* expectedClass, const char* argName) {
if (jobj == NULL) {
- LOGW("JNI WARNING: received null %s", argName);
+ ALOGW("JNI WARNING: received null %s (%s)", argName, mFunctionName);
showLocation();
abortMaybe();
return;
}
- ScopedJniThreadState ts(mEnv);
+ ScopedCheckJniThreadState ts(mEnv);
bool printWarn = false;
- Object* obj = dvmDecodeIndirectRef(mEnv, jobj);
+ Object* obj = dvmDecodeIndirectRef(self(), jobj);
if (!dvmIsHeapAddress(obj)) {
- LOGW("JNI WARNING: %s is an invalid %s reference (%p)",
- argName, indirectRefKindName(jobj), jobj);
+ ALOGW("JNI WARNING: %s is an invalid %s reference (%p) (%s)",
+ argName, indirectRefKindName(jobj), jobj, mFunctionName);
printWarn = true;
} else if (obj->clazz != expectedClass) {
- LOGW("JNI WARNING: %s arg has wrong type (expected %s, got %s)",
- argName, expectedClass->descriptor, obj->clazz->descriptor);
+ ALOGW("JNI WARNING: %s arg has wrong type (expected %s, got %s) (%s)",
+ argName, expectedClass->descriptor, obj->clazz->descriptor, mFunctionName);
printWarn = true;
}
void showLocation() {
const Method* method = dvmGetCurrentJNIMethod();
char* desc = dexProtoCopyMethodDescriptor(&method->prototype);
- LOGW(" in %s.%s:%s (%s)", method->clazz->descriptor, method->name, desc, mFunctionName);
+ ALOGW(" in %s.%s:%s (%s)", method->clazz->descriptor, method->name, desc, mFunctionName);
free(desc);
}
if (memcmp(&pExtra->magic, &kMagicCmp, 4) != 0) {
u1 buf[4];
memcpy(buf, &pExtra->magic, 4);
- LOGE("JNI: guard magic does not match (found 0x%02x%02x%02x%02x) -- incorrect data pointer %p?",
+ ALOGE("JNI: guard magic does not match (found 0x%02x%02x%02x%02x) -- incorrect data pointer %p?",
buf[3], buf[2], buf[1], buf[0], dataBuf); /* assume little endian */
return false;
}
const u2* pat = (u2*) fullBuf;
for (size_t i = sizeof(GuardedCopy) / 2; i < (kGuardLen / 2 - sizeof(GuardedCopy)) / 2; i++) {
if (pat[i] != kGuardPattern) {
- LOGE("JNI: guard pattern(1) disturbed at %p + %d", fullBuf, i*2);
+ ALOGE("JNI: guard pattern(1) disturbed at %p + %d", fullBuf, i*2);
return false;
}
}
/* odd byte; expected value depends on endian-ness of host */
const u2 patSample = kGuardPattern;
if (fullBuf[offset] != ((const u1*) &patSample)[1]) {
- LOGE("JNI: guard pattern disturbed in odd byte after %p (+%d) 0x%02x 0x%02x",
+ ALOGE("JNI: guard pattern disturbed in odd byte after %p (+%d) 0x%02x 0x%02x",
fullBuf, offset, fullBuf[offset], ((const u1*) &patSample)[1]);
return false;
}
pat = (u2*) (fullBuf + offset);
for (size_t i = 0; i < kGuardLen / 4; i++) {
if (pat[i] != kGuardPattern) {
- LOGE("JNI: guard pattern(2) disturbed at %p + %d", fullBuf, offset + i*2);
+ ALOGE("JNI: guard pattern(2) disturbed at %p + %d", fullBuf, offset + i*2);
return false;
}
}
uLong adler = adler32(0L, Z_NULL, 0);
adler = adler32(adler, (const Bytef*)dataBuf, len);
if (pExtra->adler != adler) {
- LOGE("JNI: buffer modified (0x%08lx vs 0x%08lx) at addr %p",
+ ALOGE("JNI: buffer modified (0x%08lx vs 0x%08lx) at addr %p",
pExtra->adler, adler, dataBuf);
return false;
}
static u1* debugAlloc(size_t len) {
void* result = mmap(NULL, len, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
if (result == MAP_FAILED) {
- LOGE("GuardedCopy::create mmap(%d) failed: %s", len, strerror(errno));
+ ALOGE("GuardedCopy::create mmap(%d) failed: %s", len, strerror(errno));
dvmAbort();
}
return reinterpret_cast<u1*>(result);
// TODO: we could mprotect instead, and keep the allocation around for a while.
// This would be even more expensive, but it might catch more errors.
// if (mprotect(fullBuf, totalByteCount, PROT_NONE) != 0) {
- // LOGW("mprotect(PROT_NONE) failed: %s", strerror(errno));
+ // ALOGW("mprotect(PROT_NONE) failed: %s", strerror(errno));
// }
if (munmap(fullBuf, totalByteCount) != 0) {
- LOGW("munmap failed: %s", strerror(errno));
+ ALOGW("munmap failed: %s", strerror(errno));
dvmAbort();
}
}
* data are allowed. Returns a pointer to the copied data.
*/
static void* createGuardedPACopy(JNIEnv* env, const jarray jarr, jboolean* isCopy) {
- ScopedJniThreadState ts(env);
+ ScopedCheckJniThreadState ts(env);
- ArrayObject* arrObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr);
+ ArrayObject* arrObj = (ArrayObject*) dvmDecodeIndirectRef(dvmThreadSelf(), jarr);
PrimitiveType primType = arrObj->clazz->elementClass->primitiveType;
int len = arrObj->length * dvmPrimitiveTypeWidth(primType);
void* result = GuardedCopy::create(arrObj->contents, len, true);
* back into the VM, and may or may not release the underlying storage.
*/
static void* releaseGuardedPACopy(JNIEnv* env, jarray jarr, void* dataBuf, int mode) {
- ScopedJniThreadState ts(env);
- ArrayObject* arrObj = (ArrayObject*) dvmDecodeIndirectRef(env, jarr);
+ ScopedCheckJniThreadState ts(env);
+ ArrayObject* arrObj = (ArrayObject*) dvmDecodeIndirectRef(dvmThreadSelf(), jarr);
if (!GuardedCopy::check(dataBuf, true)) {
- LOGE("JNI: failed guarded copy check in releaseGuardedPACopy");
+ ALOGE("JNI: failed guarded copy check in releaseGuardedPACopy");
abortMaybe();
return NULL;
}
static void Check_DeleteGlobalRef(JNIEnv* env, jobject globalRef) {
CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, globalRef);
- if (globalRef != NULL && dvmGetJNIRefType(env, globalRef) != JNIGlobalRefType) {
- LOGW("JNI WARNING: DeleteGlobalRef on non-global %p (type=%d)",
- globalRef, dvmGetJNIRefType(env, globalRef));
+ if (globalRef != NULL && dvmGetJNIRefType(sc.self(), globalRef) != JNIGlobalRefType) {
+ ALOGW("JNI WARNING: DeleteGlobalRef on non-global %p (type=%d)",
+ globalRef, dvmGetJNIRefType(sc.self(), globalRef));
abortMaybe();
} else {
baseEnv(env)->DeleteGlobalRef(env, globalRef);
static void Check_DeleteLocalRef(JNIEnv* env, jobject localRef) {
CHECK_JNI_ENTRY(kFlag_Default | kFlag_ExcepOkay, "EL", env, localRef);
- if (localRef != NULL && dvmGetJNIRefType(env, localRef) != JNILocalRefType) {
- LOGW("JNI WARNING: DeleteLocalRef on non-local %p (type=%d)",
- localRef, dvmGetJNIRefType(env, localRef));
+ if (localRef != NULL && dvmGetJNIRefType(sc.self(), localRef) != JNILocalRefType) {
+ ALOGW("JNI WARNING: DeleteLocalRef on non-local %p (type=%d)",
+ localRef, dvmGetJNIRefType(sc.self(), localRef));
abortMaybe();
} else {
baseEnv(env)->DeleteLocalRef(env, localRef);
CHECK_JNI_ENTRY(kFlag_CritOkay, "Esp", env, string, isCopy);
const jchar* result = baseEnv(env)->GetStringChars(env, string, isCopy);
if (gDvmJni.forceCopy && result != NULL) {
- ScopedJniThreadState ts(env);
- StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, string);
+ ScopedCheckJniThreadState ts(env);
+ StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(dvmThreadSelf(), string);
int byteCount = strObj->length() * 2;
result = (const jchar*) GuardedCopy::create(result, byteCount, false);
if (isCopy != NULL) {
sc.checkNonNull(chars);
if (gDvmJni.forceCopy) {
if (!GuardedCopy::check(chars, false)) {
- LOGE("JNI: failed guarded copy check in ReleaseStringChars");
+ ALOGE("JNI: failed guarded copy check in ReleaseStringChars");
abortMaybe();
return;
}
CHECK_JNI_ENTRY(kFlag_ExcepOkay | kFlag_Release, "Esu", env, string, utf); // TODO: show pointer and truncate string.
if (gDvmJni.forceCopy) {
if (!GuardedCopy::check(utf, false)) {
- LOGE("JNI: failed guarded copy check in ReleaseStringUTFChars");
+ ALOGE("JNI: failed guarded copy check in ReleaseStringUTFChars");
abortMaybe();
return;
}
CHECK_JNI_ENTRY(kFlag_CritGet, "Esp", env, string, isCopy);
const jchar* result = baseEnv(env)->GetStringCritical(env, string, isCopy);
if (gDvmJni.forceCopy && result != NULL) {
- ScopedJniThreadState ts(env);
- StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(env, string);
+ ScopedCheckJniThreadState ts(env);
+ StringObject* strObj = (StringObject*) dvmDecodeIndirectRef(dvmThreadSelf(), string);
int byteCount = strObj->length() * 2;
result = (const jchar*) GuardedCopy::create(result, byteCount, false);
if (isCopy != NULL) {
sc.checkNonNull(carray);
if (gDvmJni.forceCopy) {
if (!GuardedCopy::check(carray, false)) {
- LOGE("JNI: failed guarded copy check in ReleaseStringCritical");
+ ALOGE("JNI: failed guarded copy check in ReleaseStringCritical");
abortMaybe();
return;
}
static jobject Check_NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity) {
CHECK_JNI_ENTRY(kFlag_Default, "EpJ", env, address, capacity);
- if (address == NULL || capacity < 0) {
- LOGW("JNI WARNING: invalid values for address (%p) or capacity (%ld)",
- address, (long) capacity);
- abortMaybe();
- return NULL;
- }
return CHECK_JNI_EXIT("L", baseEnv(env)->NewDirectByteBuffer(env, address, capacity));
}
static jint Check_AttachCurrentThread(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
ScopedCheck sc(false, __FUNCTION__);
- sc.check(true, "vpp", vm, p_env, thr_args);
+ sc.check(true, "vpt", vm, p_env, thr_args);
return CHECK_JNI_EXIT("I", baseVm(vm)->AttachCurrentThread(vm, p_env, thr_args));
}
static jint Check_AttachCurrentThreadAsDaemon(JavaVM* vm, JNIEnv** p_env, void* thr_args) {
ScopedCheck sc(false, __FUNCTION__);
- sc.check(true, "vpp", vm, p_env, thr_args);
+ sc.check(true, "vpt", vm, p_env, thr_args);
return CHECK_JNI_EXIT("I", baseVm(vm)->AttachCurrentThreadAsDaemon(vm, p_env, thr_args));
}