I have saw many question about Fatal signal 11 (SIGSEGV), code 1 on stackoverflow,but no one has an answer.
my JNI code :
JNIEXPORT jbyteArray JNICALL
Java_com_btc_testtwo_ProxyApplication_decrypt(JNIEnv *env, jobject instance,
jbyteArray srcdata_) {
jbyte *srcdata = env->GetByteArrayElements(srcdata_, NULL);
print_debug("come in");
while (*srcdata) {
*srcdata ^= 0xF;
*srcdata++;
}
print_debug("come out");
env->ReleaseByteArrayElements(srcdata_, srcdata, 0);
}
I wanna know if the bit operation XOR changed the memory size.My suspicion is that the error caused by the memory error.I don't know how the code cause this.
ReleaseByteArrayElements(srcdata_, srcdata, 0) will fail if GetByteArrayElements gave you a copy of the array data, because you've incremented srcdata so that it no longer contains the same address that you got from GetByteArrayElements.
Also, your while-loop can potentially access data past the end of the array, because you don't take the value of GetArrayLength(srcdata_) into account.
Related
My Minecraft server crushed caused by insufficient spaces. About 2 hours before crushed, there were some plugins printing exception stack traces including java.io.ioexception: 设备上没有空间 (means java.io.IOException: No space left on device). After I restart it, I found that all the buildings players built in the 2 hours disappeared, and no any plugins can restore it (include CoreProtect, because of insufficient spaces, it can not submit database transactions).
In order to close server immediately when there's no enough spaces, I decided to develop a plugin. Because there's no way to listen exceptions thrown by all threads, I implemented this function by listen logs.
Any code print log like java.io.ioexception: ${message} or [...] ... [...]: java.io.ioexception: ${message} will trigger the shutdown of server.
Pay attention to the error message: In some platforms, it's 设备上没有空间; In some others platforms, it's No space left on device... So It's necessary to get the localized version of it firstly.
This error message, comes from Operating System, is strerror(28) (C++ function) in Windows or Linux. So I create a native function to invoke it:
// cn.chuanwise.nessc.errno.ErrorMessage;
public class ErrorMessage {
public native static String of(int errno, Locale locale);
}
#include "localed-error-message-native.h"
#include <locale>
#include <string.h>
JNIEXPORT jstring JNICALL Java_cn_chuanwise_nessc_errno_ErrorMessage_of(JNIEnv* env, jclass clz, jint code, jobject locale) {
// find locale class
const jclass locale_class = env->FindClass("java/util/Locale");
const jmethodID to_string_method = env->GetMethodID(locale_class, "toString", "()Ljava/lang/String;");
const jobject locale_string = env->CallObjectMethod(locale, to_string_method);
const char* locale_name = env->GetStringUTFChars(reinterpret_cast<jstring>(locale_string), nullptr);
// set locale
std::setlocale(LC_ALL, locale_name);
const char* strerr = strerror(static_cast<int>(code));
if (strerr == nullptr) {
return nullptr;
} else {
return env->NewStringUTF(strerr);
}
}
ErrorMessage.of(28, Locale.getDefault()) returns No space left on device in my device, but this code throws java.io.IOException: 设备上没有空间 in my device:
final File file = new File("test");
// ...
try (OutputStream outputStream = new FileOutputStream(file)) {
final byte[] buf = new byte[1024];
while (true) {
outputStream.write(buf);
}
}
How to get the localized return string of strerror?
I am developing an Android project with OpenCV and JNI.
Actually I am changing the face-detection sample.
The problem I have is that when I pass a cv::Mat reference it gives some strane output and it is not passed well.
To put you in situation, I have this in my FdActivity.java, which is the main activity of my android app:
public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
rgb = inputFrame.rgba();
Mat res = mNativeDetector.process(rgb);
return res;
}
The process function is like this:
public Mat process(Mat rgb) {
Mat n = null;
if(rgb.empty()) {
System.out.println("Empty Image");
}
else {
System.out.println("The image is " + rgb.rows() + "x" + rgb.cols());
n = nativeSkinFilter(mNativeObj, rgb.getNativeObjAddr());
}
return n;
}
Where nativeSkinFilter is a native function with this declaration
private static native Mat nativeSkinFilter(long thiz, long inputImage);
In the C++ side I have the function declaration (DetectionBasedTracker.h):
JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSkinFilter (JNIEnv *, jclass, jlong);
The only thing I want to do is return the same image, just passing by the C++ function (more complex implementation will come as soon as I know I can correctly pass a matrix), so the code is just like this (DetectionBasedTracker.cpp):
JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSkinFilter (JNIEnv * jenv,jclass,jlong rgb)
{
Mat* rgba = (Mat*) rgb;
if(rgb == 0) {
LOGD("Null matrix");
}
else {
LOGD("The matrix is not null. It has %i rows and %i columns", (*rgba).rows, (*rgba).cols);
}
return (jlong)rgb;
}
The ouptut I have is the following:
07-07 13:00:07.671: I/Choreographer(14980): Skipped 55 frames! The application may be doing too much work on its main thread.
07-07 13:00:07.701: E/BufferQueue(14980): [unnamed-14980-0] dequeueBuffer: min undequeued buffer count (2) exceeded (dequeued=6 undequeudCount=0)
07-07 13:00:07.741: I/JavaCameraView(14980): Preview Frame received. Need to create MAT and deliver it to clients
07-07 13:00:07.741: I/JavaCameraView(14980): Frame size is 576000
07-07 13:00:07.761: I/System.out(14980): The image is 480x800
07-07 13:00:07.761: D/FaceDetection/DetectionBasedTracker(14980): The matrix is not null. It has 1937716000 rows and 0 columns
07-07 13:00:07.761: E/cv::error()(14980): OpenCV Error: Assertion failed (src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols) in void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean), file /home/reports/ci/slave_desktop/50-SDK/opencv/modules/java/generator/src/cpp/utils.cpp, line 97
07-07 13:00:07.761: E/org.opencv.android.Utils(14980): nMatToBitmap catched cv::Exception: /home/reports/ci/slave_desktop/50-SDK/opencv/modules/java/generator/src/cpp/utils.cpp:97: error: (-215) src.dims == 2 && info.height == (uint32_t)src.rows && info.width == (uint32_t)src.cols in function void Java_org_opencv_android_Utils_nMatToBitmap2(JNIEnv*, jclass, jlong, jobject, jboolean)
07-07 13:00:07.761: A/libc(14980): Fatal signal 11 (SIGSEGV) at 0x0000000a (code=1), thread 15115 (Thread-5379)
07-07 13:00:07.791: E/BufferQueue(14980): [unnamed-14980-0] dequeueBuffer: min undequeued buffer count (2) exceeded (dequeued=5 undequeudCount=1)
07-07 13:00:07.801: I/JavaCameraView(14980): Preview Frame received. Need to create MAT and deliver it to clients
07-07 13:00:07.801: I/JavaCameraView(14980): Frame size is 576000
I think I have tried everything, but it seems the correct way and it's still failing.
Can you please please help me?
Thank you very much for your time! Help will be really appreciated.
this
JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSkinFilter (JNIEnv *, jclass, jlong);
should be this
JNIEXPORT jlong JNICALL Java_org_opencv_samples_facedetect_DetectionBasedTracker_nativeSkinFilter (JNIEnv *, jclass, jobject, jlong);
because a call like this in java
n = nativeSkinFilter(mNativeObj, rgb.getNativeObjAddr());
expects 4 parameters:
JNEnv (obvious)
jclass is the class. Or if you are invoking the method from an instance it will be jobject
jobject as you are passing in some object
jlong now this is the actual matrix you are looking for
in the c++ side, after the second parameter, the parameters you pass in on the Java side are passed. In other words, every call via Java->C++ (whether instance or static function) on the c++ side the first 2 parameters are mandatory. Then follows your parameters between "(" and ")" in the Java code.
I have a problem when running a testcase in debug-mode: I get a pop-up-box with the message "Unhandled exception at 0x7c812fd3 in Test.exe: 0xE0000003: 0xe0000003.". The code breaks in free.c:
void __cdecl _free_base (void * pBlock)
{
int retval = 0;
if (pBlock == NULL)
return;
RTCCALLBACK(_RTC_Free_hook, (pBlock, 0));
retval = HeapFree(_crtheap, 0, pBlock);
if (retval == 0)
{
errno = _get_errno_from_oserr(GetLastError());
}
}
at line "retval =..." with _crtheap = 0x00df0000 and pBlock = 0x967c93d3. The call stack breaks at "kernel32.dll!7c812fd3() " and another entry further down in the call stack:
">msvcr100d.dll!_free_base(void * pBlock=0x967c93d3) Line 50 + 0x13 bytes".
I have googled quite a bit and the problem might come from freeing memory severel times.
Despite this vague and messy description can anyone hint how to locate the problem ? and maybe how to fix it ?
What strikes me a bit odd is that I do not experience this when running the test in release-mode...
Kind regards,
Svend
Have you tried to run these testcases under visual studio debugger?
Debugger should catch this exception and you can verify call stack and locate where issue is.
I have this code in a big project that makes a connection to a MySQL database, and does not work:
boost::shared_ptr<sql::Connection> connection;
sql::Driver *driver = get_driver_instance();
assert(driver != 0);
std::string server = "servname", user = "pietro", password = "abc";
try
{
connection.reset(driver->connect(server, user, password));
assert(connection != 0);
if(connection->isClosed() == false) // <-- segmentation fault
{
}
}
I get a segmentation fault where indicated (all parameters are valid).
However, this same code works in a test project.
Going into the sql::Connection::isClosed() member function with a debugger, I obtain no information about the possible cause; here is where I get:
mysql-connector-c++-1.0.5/driver/mysql_connection.cpp - line 430
/* {{{ MySQL_Connection::checkClosed() -I- */
void
MySQL_Connection::checkClosed()
{
CPP_ENTER_WL(intern->logger, "MySQL_Connection::checkClosed");
if (!intern->is_valid) {
throw sql::SQLException("Connection has been closed");
}
}
This checkClosed() function is successfully executed seven times from connection.reset() just before. The value of the "intern" pointer does not change and is not null at this stage.
When I check if the connection is closed, the checkClosed() function is run again. Now the "intern" pointer value is 0x8, a location I cannot access.
Here I get a SIGSEGV, segmentation fault.
Let me know if you would like the disassembled code...
Platform:
MySQL 5.x
MySQL Connector/C++ 1.0.5
Linux - OpenSuse 11.4
P.S.:
I noticed that all the shared_ptr's member functions work as expected:
connection.get(); // = 0x8fb4a0
connection.use_count(); // = 1
connection.unique(); // = 1
while all the calls done on the pointed object cause the segmentation fault (SIGABRT):
connection->getClientInfo();
connection->isClosed();
either your connection deleted, or you have memory corruption. use valgrind to find answer
I have the following native routine:
void sendMessage(const char* text)
{
JNIEnv* env;
if(!_jvm)
return;
_jvm->AttachCurrentThread(&env, NULL);
if(!_nativesCls)
_nativesCls = env->FindClass("com/foo/BaseLib");
if(_nativesCls == 0)
return;
jstring message = env->NewStringUTF(text);
if(!_sendStr)
_sendStr = env->GetStaticMethodID(_nativesCls, "onMessage", "(Ljava/lang/String;)V");
if(_sendStr)
env->CallStaticVoidMethod(_nativesCls, _sendStr, message);
//env->ReleaseStringUTFChars(message, text); // <----- * NOT WORKING
}
If I run this as is, it works fine up until memory fills up and I receive:
ReferenceTable overflow (max=512)
I thought adding the commented line above would fix the issue but it just causes the app to bomb out at that point.
Any suggestions?
DeleteLocalRef(). Just like any other Java object that was allocated within JNI. However, it will be automatically garbage-collected once the JNI method returns. Details here: http://download.oracle.com/javase/1.3/docs/guide/jni/spec/design.doc.html#1242