I am using Android Studio Giraffe | 2022.3.1 Patch 2 (should probably update) and encounter annoying crashes of the Debugger in the app(disassembly) in either of the methods
art::StackVisitor::WalkStack
art::jit::JitCodeCache::GetJniStubCode
The underlying codebase is fairly large and basically retrieves uvc frames using saki4510t/UVCCamera library from webcamera devices, then manipulates those UVC frames inside a custom jni c++ part and then transfers the frames into the java part to finally display the images inside an imageview.
Certainly, lots of things can go wrong here but this construct worked so far well. However investigations inside the code base using native + java debugger became impossible due to breaks in said art methods.
I’ve tried to break down a small example to reproduce the crash.The example is a modified native c++ template project selected from Android Studio’s gallery:
public class MainActivityextends AppCompatActivity {
// Used to load the 'jnibugdemo' library on application startup.
static {
System.loadLibrary("jnibugdemo");
}
private Thread MainProcess;
boolean MainProcessON;
private ActivityMainBindingbinding;
MainProcessClass currentMainProcessClass;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
// Example of a call to a native method
TextView tv = binding.sampleText;
tv.setText(stringFromJNI());
MainProcessON = false;
}
@Override
public void onResume() {
super.onResume();
if( !MainProcessON) {
MainProcessON = true;
currentMainProcessClass= new MainProcessClass();
MainProcess= new Thread(currentMainProcessClass);
MainProcess.start();
}
}
private class MainProcessClassimplements Runnable {
Bitmap.Config currentScreen_conf;
Bitmap currentScreen;
int width,height;
byte[] RawFrameBufferIn;
byte[] RawFrameBufferOut;
ByteBuffer currentScreen_bytebuffer;
int currentScreensize;
byte bmp_rgbValues[];
MainProcessClass() {
width = 640;
height = 480;
currentScreen_conf= Bitmap.Config.ARGB_8888;
currentScreen= Bitmap.createBitmap(width, height, currentScreen_conf);
currentScreensize = currentScreen.getRowBytes()*currentScreen.getHeight()*4;
bmp_rgbValues = new byte[currentScreensize];
currentScreen_bytebuffer = ByteBuffer.wrap(bmp_rgbValues);
currentScreen.copyPixelsToBuffer(currentScreen_bytebuffer);
RawFrameBufferIn= new byte [width*height * 2];
}
public void run() {
int count_c, count_r, count_b;
byte check;
while (MainProcessON) {
// currentScreen_bytebuffer = ByteBuffer.wrap(bmp_rgbValues);
// currentScreen.copyPixelsToBuffer(currentScreen_bytebuffer);
RawFrameBufferOut= nativeGetRawFrames(RawFrameBufferIn);
// RawFrameBufferOut = nativeGetRawFrames(RawFrameBufferIn);
count_b = 0;
for (count_c = 0; count_c<width; count_c++) {
for (count_r = 0; count_r<height; count_r++) {
check = (byte)(RawFrameBufferOut[2*(count_c*height + count_r)] &0xFF);
bmp_rgbValues[count_b] = check;
count_b++;
bmp_rgbValues[count_b] = check;
count_b++;
bmp_rgbValues[count_b] = check;
count_b++;
count_b++;
}
}
currentScreen_bytebuffer.rewind();
currentScreen.copyPixelsFromBuffer(currentScreen_bytebuffer);
// SetImageView(currentScreen);
try {
sleep(30);
} catch (InterruptedException ex) {
throw new RuntimeException(ex);
}
}
}
}
public native byte[] nativeGetRawFrames(byte[] source);
public native String stringFromJNI();
}
Inside the native-lib.cpp this method
Java_com_example_jnibugdemo_MainActivity_nativeGetRawFrames(JNIEnv *env, jobjectthiz,
jbyteArray source) {
int nop;
nop = 1;
return source;
}
needs to be added (which needs to be created using right-click on the java method: public native byte[] nativeGetRawFrames(byte[] source); select “Show content actions” and select “Create JINI function for nativeGetRawFrames. This creates inside the native_lib.cpp the function body which needs then to be modied accordingly to the snipped given above.
If this is let run on a real device using debugger after a few seconds the mentioned breaks/crashs can be observed. It seems the crash is solely caused by accessing the bitmap – so it breaks also without invoking the native method. However not reproducible I see occasionally also breaks in the mentioned art methods without touching the bitmap if the native method is only invoked.
Would be glad if someone could give advice here.