ART如何实现Exception.printStackTrace

本文深入解析ART运行时系统中如何通过寄存器和栈帧结构实现C/C++程序的函数调用堆栈跟踪,重点讨论了如何在Java环境中重现类似C/C++的调试体验。

大家都很熟悉Exception.printStackTrace,而且也非常的常用。不过,各位有没有想过应该如何实现呢?


想象一下,当我们调试一个C/C++程序的时候,我们也能看到函数的调用堆栈,一定会想,这究竟是怎么做到呢?因为ART运行的也是机器码,那么它们也一定有共同的地方吧。


当然,我们并不是真正的去了解一个C/C++程序是如何实现调试的,我们只是借鉴一下它的原理。

以ARM为例,我们都知道,当一个函数运行时,CPU的寄存器PC保存了当前指令的地址,而寄存器SP保存了当前的堆栈栈顶地址。当我们调用一个函数时,需要用指令BL <地址偏移> ,这个时候,CPU会将BL后面的指令地址放入寄存器LR中,然后跳转到子函数的入口。

BL 是Branch Link的缩写,LR 是Link Register的缩写。对于子函数,如果要正确返回,它必须在入口处 PUSH LR,当函数返回时,POP LR,然后再 B LR。 (更简洁的方法是 POP PC)。如果我们知道函数所使用的栈帧大小,那么我们就可以知道上个函数的调用地址了。

至于栈帧的大小,有很多方法,比如,将它们和函数的入口地址做个映射,根据函数的入口地址获取栈帧的大小,配合保存在栈固定位置的LR寄存器的值,就可以获得完整的调用栈了。


根据《ART如何传递参数》这一章节,我们知道,一个普通java函数在被转换为本地函数后,它的栈结构是这样的。

PUSH LR
.... <其他寄存器> ....
.... <内部变量/参数调用必须> ....
ArtMethod *
 

我们知道栈顶元素是ArtMethod的指针,也就是这个栈帧所代表的函数。


那么,ArtMethod能够获取栈帧的大小吗?我想是肯定的。


仔细阅读以下源代码,让我们找到看:


package com.XiaoLian; import android.app.Activity; import android.os.Build; import android.os.Handler; import android.os.RemoteException; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.WindowManager; import com.XiaoLian.IPCCond.IPCService; /* loaded from: classes.dex */ public class StartGame { private static WindowManager.LayoutParams Touch_Params; private static View Touch_View; private static WindowManager manager; public static void showFloatWindow(Activity activity) { manager = (WindowManager) activity.getSystemService("window"); WindowManager.LayoutParams layoutParams = new WindowManager.LayoutParams(); layoutParams.systemUiVisibility = 5894; layoutParams.type = Build.VERSION.SDK_INT >= 26 ? 2038 : 2003; layoutParams.gravity = 51; layoutParams.format = -2; ((ViewGroup.LayoutParams) layoutParams).width = -1; ((ViewGroup.LayoutParams) layoutParams).height = -1; layoutParams.flags = 1098909496; if (Build.VERSION.SDK_INT >= 28) { layoutParams.layoutInDisplayCutoutMode = 1; } Touch_View = new View(activity); Touch_Params = new WindowManager.LayoutParams(); Touch_Params.type = Build.VERSION.SDK_INT >= 26 ? 2038 : 2003; Touch_Params.gravity = 51; Touch_Params.format = -2; ((ViewGroup.LayoutParams) Touch_Params).width = 770; ((ViewGroup.LayoutParams) Touch_Params).height = 780; Touch_Params.x = 60; Touch_Params.y = 60; if (Build.VERSION.SDK_INT >= 28) { Touch_Params.layoutInDisplayCutoutMode = 1; } Touch_Params.flags = 1098909480; Touch_View.setOnTouchListener(new View.OnTouchListener() { // from class: com.XiaoLian.StartGame.100000000 @Override // android.view.View.OnTouchListener public boolean onTouch(View view, MotionEvent motionEvent) { try { if (MainActivity.app_Operation_mode_root) { IPCService.GetIPC().MotionEventClick(motionEvent.getAction(), motionEvent.getRawX(), motionEvent.getRawY()); } else { SuperJNI.MotionEventClick(motionEvent.getAction(), motionEvent.getRawX(), motionEvent.getRawY()); } } catch (RemoteException e) { e.printStackTrace(); } return true; } }); TV tv = new TV(activity); layoutParams.token = tv.getApplicationWindowToken(); Touch_Params.token = Touch_View.getApplicationWindowToken(); manager.addView(tv, layoutParams); manager.addView(Touch_View, Touch_Params); if (MainActivity.app_Operation_mode_root) { updateTouchWinSize(); } else { updateTouchWinSize_not_root(); } } public static void updateTouchWinSize() { Handler handler = new Handler(); handler.postDelayed(new Runnable(handler) { // from class: com.XiaoLian.StartGame.100000001 private final Handler val$handler; { this.val$handler = r6; } @Override // java.lang.Runnable public void run() { try { float[] GetImGuiwinsize = IPCService.GetIPC().GetImGuiwinsize(); StartGame.Touch_Params.x = (int) GetImGuiwinsize[0]; StartGame.Touch_Params.y = (int) GetImGuiwinsize[1]; ((ViewGroup.LayoutParams) StartGame.Touch_Params).width = (int) GetImGuiwinsize[2]; ((ViewGroup.LayoutParams) StartGame.Touch_Params).height = (int) GetImGuiwinsize[3]; StartGame.manager.updateViewLayout(StartGame.Touch_View, StartGame.Touch_Params); } catch (RemoteException e) { e.printStackTrace(); } this.val$handler.postDelayed(this, (long) 17); } }, (long) 17); } public static void updateTouchWinSize_not_root() { Handler handler = new Handler(); handler.postDelayed(new Runnable(handler) { // from class: com.XiaoLian.StartGame.100000002 private final Handler val$handler; { this.val$handler = r6; } @Override // java.lang.Runnable public void run() { float[] GetImGuiwinsize = SuperJNI.GetImGuiwinsize(); StartGame.Touch_Params.x = (int) GetImGuiwinsize[0]; StartGame.Touch_Params.y = (int) GetImGuiwinsize[1]; ((ViewGroup.LayoutParams) StartGame.Touch_Params).width = (int) GetImGuiwinsize[2]; ((ViewGroup.LayoutParams) StartGame.Touch_Params).height = (int) GetImGuiwinsize[3]; StartGame.manager.updateViewLayout(StartGame.Touch_View, StartGame.Touch_Params); this.val$handler.postDelayed(this, (long) 17); } }, (long) 17); } } package com.XiaoLian; import android.view.Surface; /* loaded from: classes.dex */ public class SuperJNI { public static native float[] GetImGuiwinsize(); public static native void MotionEventClick(int i, float f, float f2); public static native void setKey(String str); public static native void setPid(int i); public static native void setSurface(Surface surface); public static native void setUUid(String str); public static native String start(int i, int i2); } package com.XiaoLian; import android.content.Context; import android.os.RemoteException; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import com.XiaoLian.IPCCond.IPCService; /* loaded from: classes.dex */ public class SV extends SurfaceView implements SurfaceHolder.Callback { @Override // android.view.SurfaceHolder.Callback public void surfaceDestroyed(SurfaceHolder surfaceHolder) { } public SV(Context context) { super(context); setZOrderOnTop(true); getHolder().setFormat(-2); getHolder().addCallback(this); } @Override // android.view.SurfaceHolder.Callback public void surfaceCreated(SurfaceHolder surfaceHolder) { Log.e("DrawView", "surfaceCreated"); surfaceHolder.setType(2); try { IPCService.GetIPC().setSurface(surfaceHolder.getSurface()); } catch (RemoteException e) { e.printStackTrace(); } } @Override // android.view.SurfaceHolder.Callback public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) { try { IPCService.GetIPC().start(i2, i3); } catch (RemoteException e) { e.printStackTrace(); } } } package com.XiaoLian; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.provider.Settings; import android.util.Log; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.net.HttpURLConnection; import java.net.URL; import java.security.MessageDigest; /* loaded from: classes.dex */ public class Tools { /* renamed from: 申请ROOT reason: contains not printable characters */ public static void m9ROOT() { try { Runtime.getRuntime().exec("su"); } catch (IOException e) { } } /* renamed from: 检测ROOT reason: contains not printable characters */ public static boolean m8ROOT() { String[] strArr = {"/system/bin/", "/system/xbin/"}; try { if (0 < strArr.length) { File file = new File(new StringBuffer().append(strArr[0]).append("su").toString()); if (file.exists()) { if (file.canExecute()) { return true; } } return false; } } catch (Exception e) { e.printStackTrace(); } return false; } /* renamed from: 创建文件 reason: contains not printable characters */ public static void m4(String str) { File file = new File(str); if (file.exists()) { file.delete(); } try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } } /* renamed from: 创建文件夹 reason: contains not printable characters */ public static void m5(String str) { File file = new File(str); if (!file.exists()) { file.mkdirs(); } } /* renamed from: 写入文件 reason: contains not printable characters */ public static void m2(String str, String str2) { try { FileWriter fileWriter = new FileWriter(str); fileWriter.write(str2); fileWriter.close(); } catch (IOException e) { } } public static boolean deleteFile(String str) { return new File(str).delete(); } /* renamed from: 删除文件 reason: contains not printable characters */ public static boolean m6(String str) { if (str == null || str.length() == 0 || str.trim().length() == 0) { return true; } File file = new File(str); if (!file.exists()) { return true; } if (file.isFile()) { return file.delete(); } if (!file.isDirectory()) { return false; } File[] listFiles = file.listFiles(); for (File file2 : listFiles) { if (file2.isFile()) { file2.delete(); } else if (file2.isDirectory()) { deleteFile(file2.getAbsolutePath()); } } return file.delete(); } /* renamed from: 读取文件 reason: contains not printable characters */ public static String m11(String str) { String str2 = ""; try { BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(new File(str)), "UTF-8")); String str3 = null; while (true) { String readLine = bufferedReader.readLine(); if (readLine == null) { break; } str2 = new StringBuffer().append(str2).append(readLine).toString(); } } catch (Exception e) { e.printStackTrace(); } return str2; } public static void RunShell(String str) { try { Runtime.getRuntime().exec(str, (String[]) null, (File) null); } catch (Exception e) { e.printStackTrace(); } } public static void Sshell(String str) { Log.d("Alice-", str); new Thread(new Runnable(str) { // from class: com.XiaoLian.Tools.100000000 private final String val$shell; { this.val$shell = r6; } @Override // java.lang.Runnable public void run() { try { DataOutputStream dataOutputStream = new DataOutputStream(Runtime.getRuntime().exec("sh").getOutputStream()); dataOutputStream.write(this.val$shell.getBytes()); dataOutputStream.writeBytes("\n"); dataOutputStream.flush(); dataOutputStream.close(); } catch (Exception e) { e.printStackTrace(); } } }).start(); } /* renamed from: 写出资源文件 reason: contains not printable characters */ public static boolean m3(Context context, String str, String str2) { File file = new File(str); if (!file.exists() && !file.mkdirs()) { return false; } try { InputStream open = context.getAssets().open(str2); FileOutputStream fileOutputStream = new FileOutputStream(new File(file, str2)); byte[] bArr = new byte[1024]; while (true) { int read = open.read(bArr); if (-1 == read) { open.close(); fileOutputStream.flush(); fileOutputStream.close(); return true; } fileOutputStream.write(bArr, 0, read); } } catch (IOException e) { e.printStackTrace(); return false; } } /* renamed from: 打开软件 reason: contains not printable characters */ public static boolean m7(Context context, String str) { PackageManager packageManager = context.getPackageManager(); new Intent(); context.startActivity(packageManager.getLaunchIntentForPackage(str)); return true; } /* renamed from: 获取机器码 reason: contains not printable characters */ public static String m10(Context context) { return Settings.Secure.getString(context.getContentResolver(), "android_id"); } public static String UrlPost(String str, String str2) { String str3 = ""; try { HttpURLConnection httpURLConnection = (HttpURLConnection) new URL(str).openConnection(); httpURLConnection.setReadTimeout(9000); httpURLConnection.setRequestMethod("POST"); httpURLConnection.getOutputStream().write(str2.getBytes()); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream())); StringBuffer stringBuffer = new StringBuffer(); while (true) { String readLine = bufferedReader.readLine(); if (readLine == null) { break; } stringBuffer.append(readLine); } str3 = stringBuffer.toString(); } catch (IOException e) { } return str3; } public static String encodeMD5(String str) { try { MessageDigest instance = MessageDigest.getInstance("MD5"); instance.update(str.getBytes("UTF-8")); byte[] digest = instance.digest(); StringBuilder sb = new StringBuilder(); for (int i = 0; i < digest.length; i++) { sb.append(String.format("%02X", new Byte(digest[i]))); } return sb.toString().toLowerCase(); } catch (Exception e) { e.printStackTrace(); return ""; } } } package com.XiaoLian; import android.content.Context; import android.graphics.SurfaceTexture; import android.os.RemoteException; import android.util.Log; import android.view.Surface; import android.view.TextureView; import com.XiaoLian.IPCCond.IPCService; /* loaded from: classes.dex */ public class TV extends TextureView implements TextureView.SurfaceTextureListener { @Override // android.view.TextureView.SurfaceTextureListener public void onSurfaceTextureSizeChanged(SurfaceTexture surfaceTexture, int i, int i2) { } @Override // android.view.TextureView.SurfaceTextureListener public void onSurfaceTextureUpdated(SurfaceTexture surfaceTexture) { } public TV(Context context) { super(context); setOpaque(true); setSurfaceTextureListener(this); } @Override // android.view.TextureView.SurfaceTextureListener public void onSurfaceTextureAvailable(SurfaceTexture surfaceTexture, int i, int i2) { try { if (MainActivity.app_Operation_mode_root) { IPCService.GetIPC().start(i, i2); IPCService.GetIPC().setSurface(new Surface(surfaceTexture)); } else { SuperJNI.start(i, i2); SuperJNI.setSurface(new Surface(surfaceTexture)); } } catch (RemoteException e) { e.printStackTrace(); } Log.e("TV", "surfaceCreated_"); } @Override // android.view.TextureView.SurfaceTextureListener public boolean onSurfaceTextureDestroyed(SurfaceTexture surfaceTexture) { Log.e("NDK-java", "onSurfaceTextureDestroyed"); return false; } } package com.XiaoLian; import android.content.ClipboardManager; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.icu.text.SimpleDateFormat; import android.media.MediaPlayer; import android.provider.Settings; import android.text.TextUtils; import android.util.Log; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; import java.math.BigInteger; import java.nio.charset.StandardCharsets; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.sql.Timestamp; import java.util.Date; import java.util.Random; /* loaded from: classes.dex */ public class Util { private static MediaPlayer mMediaPlayer; public static Context getContext() { return MainActivity.getContext; } /* renamed from: 获取卡密 reason: contains not printable characters */ public static String m12() { ClipboardManager clipboardManager = (ClipboardManager) getContext().getSystemService("clipboard"); if (clipboardManager != null && clipboardManager.hasPrimaryClip() && clipboardManager.getPrimaryClip().getItemCount() > 0) { String valueOf = String.valueOf(clipboardManager.getPrimaryClip().getItemAt(0).getText()); if (!TextUtils.isEmpty(valueOf)) { return valueOf; } } return "获取卡密失败"; } public static String imei() { return Settings.System.getString(getContext().getContentResolver(), "android_id"); } public static String getTimeStateNew(String str) { String str2 = str; if (Long.valueOf(str2).longValue() / Long.valueOf("1000000000000").longValue() < ((long) 1) && Long.valueOf(str2).longValue() / Long.valueOf("1000000000").longValue() >= ((long) 1)) { str2 = new StringBuffer().append(str2).append("000").toString(); } Timestamp timestamp = new Timestamp(Long.valueOf(str2).longValue()); Timestamp timestamp2 = new Timestamp(System.currentTimeMillis()); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); long j = (long) 86400000; long j2 = (long) 3600000; long j3 = (long) 60000; long time = timestamp2.getTime() - timestamp.getTime(); if (time / j >= ((long) 3)) { return simpleDateFormat.format((Date) timestamp); } long j4 = time / j; if (j4 <= ((long) 2) && j4 >= ((long) 1)) { return new StringBuffer().append(j4).append("天前").toString(); } long j5 = time / j2; if (j5 >= ((long) 1)) { return new StringBuffer().append(j5).append("小時前").toString(); } long j6 = time / j3; if (j6 >= ((long) 1)) { return new StringBuffer().append(j6).append("分鐘前").toString(); } return "剛剛"; } public static boolean isRoot() { try { Process exec = Runtime.getRuntime().exec("su"); OutputStream outputStream = exec.getOutputStream(); outputStream.write("\n".getBytes()); outputStream.flush(); outputStream.write("exit".getBytes()); outputStream.flush(); outputStream.write("\n".getBytes()); outputStream.flush(); int waitFor = exec.waitFor(); outputStream.close(); return waitFor == 0; } catch (Exception e) { return false; } } private static void load(Context context, File file, int i, String str) { for (int i2 = 1; i2 < i; i2++) { File file2 = new File(new StringBuffer().append(new StringBuffer().append(new StringBuffer().append(new StringBuffer().append(file.getPath()).append("/").toString()).append(str).toString()).append(i2).toString()).append(".png").toString()); if (!file2.exists()) { try { InputStream open = context.getAssets().open(new StringBuffer().append(new StringBuffer().append(new StringBuffer().append("image/").append(str).toString()).append(i2).toString()).append(".png").toString()); FileOutputStream fileOutputStream = new FileOutputStream(file2); byte[] bArr = new byte[1048576]; while (true) { int read = open.read(bArr); if (read == -1) { break; } fileOutputStream.write(bArr, 0, read); } fileOutputStream.flush(); open.close(); fileOutputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } } public static void loadImage(Context context, String str, String str2) { try { String[] list = context.getAssets().list(str); if (list.length > 0) { File file = new File(str2); if (!file.exists()) { file.mkdirs(); } for (String str3 : list) { loadImage(context, new StringBuffer().append(new StringBuffer().append(str).append("/").toString()).append(str3).toString(), new StringBuffer().append(new StringBuffer().append(str2).append("/").toString()).append(str3).toString()); } return; } InputStream open = context.getAssets().open(str); FileOutputStream fileOutputStream = new FileOutputStream(new File(str2)); byte[] bArr = new byte[1024]; while (true) { int read = open.read(bArr); if (read == -1) { fileOutputStream.flush(); open.close(); fileOutputStream.close(); return; } fileOutputStream.write(bArr, 0, read); } } catch (Exception e) { e.printStackTrace(); } } public static String getFileMd5(File file) { byte[] bArr = new byte[1024]; try { if (!file.isFile()) { return ""; } MessageDigest instance = MessageDigest.getInstance("MD5"); FileInputStream fileInputStream = new FileInputStream(file); while (true) { int read = fileInputStream.read(bArr, 0, 1024); if (read == -1) { fileInputStream.close(); return String.format("%1$032x", new BigInteger(1, instance.digest())); } instance.update(bArr, 0, read); } } catch (Exception e) { e.printStackTrace(); return null; } } public static String getBinData() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < 1024; i++) { String hexString = Integer.toHexString(new Random().nextInt(255) & 255); sb.append("\\x"); if (hexString.length() == 1) { sb.append("0"); } sb.append(hexString); } return sb.toString(); } private static String getMd5(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException { byte[] digest = MessageDigest.getInstance("MD5").digest(str.getBytes(StandardCharsets.UTF_8)); StringBuilder sb = new StringBuilder(); for (byte b : digest) { sb.append(Integer.toHexString((255 & b) | -256).substring(6)); } return sb.toString(); } public static String getAndroidID() { String[] strArr = {"/data/local/tmp/.system.r350.x29", "/data/app/install_check", "/data/data/android/code_cache/pmx32.dat"}; StringBuilder sb = new StringBuilder(); for (String str : strArr) { File file = new File(str); if (!file.exists()) { runShell(new StringBuffer().append(new StringBuffer().append(new StringBuffer().append(new StringBuffer().append(new StringBuffer().append(new StringBuffer().append("echo -e -n \"").append(getBinData()).toString()).append("\" > ").toString()).append(str).toString()).append("\n").toString()).append("chmod 644 ").toString()).append(str).toString(), true); } sb.append(getFileMd5(file)).append("&"); } try { return getMd5(sb.toString()); } catch (UnsupportedEncodingException | NoSuchAlgorithmException e) { e.printStackTrace(); return null; } } public static byte[] runShell(String str, boolean z) { try { Process exec = Runtime.getRuntime().exec(z ? "su" : "sh"); InputStream inputStream = exec.getInputStream(); InputStream errorStream = exec.getErrorStream(); OutputStream outputStream = exec.getOutputStream(); outputStream.write("\n".getBytes()); outputStream.flush(); outputStream.write(str.getBytes()); outputStream.flush(); outputStream.write("\n".getBytes()); outputStream.flush(); outputStream.write("exit".getBytes()); outputStream.flush(); outputStream.write("\n".getBytes()); outputStream.flush(); byte[] readInputStream = readInputStream(inputStream, false); byte[] readInputStream2 = readInputStream(errorStream, false); exec.waitFor(); inputStream.close(); errorStream.close(); outputStream.close(); if (new String(readInputStream2).trim().isEmpty()) { return readInputStream; } return new StringBuffer().append(new StringBuffer().append(new StringBuffer().append(new StringBuffer().append(new StringBuffer().append("Shell Result : \n").append(new String(readInputStream)).toString()).append("\n").toString()).append("Shell Error : \n").toString()).append(new String(readInputStream2)).toString()).append("\n").toString().getBytes(); } catch (Throwable th) { return new StringBuffer().append("Application Error : \n").append(Log.getStackTraceString(th)).toString().getBytes(); } } public static byte[] readInputStream(InputStream inputStream, boolean z) { try { ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); byte[] bArr = new byte[1024]; while (true) { int read = inputStream.read(bArr); if (read == -1) { break; } byteArrayOutputStream.write(bArr, 0, read); } if (z) { inputStream.close(); byteArrayOutputStream.close(); } return byteArrayOutputStream.toByteArray(); } catch (Throwable th) { return Log.getStackTraceString(th).getBytes(); } } public static void doPlay(File file) { mMediaPlayer = new MediaPlayer(); try { mMediaPlayer.setDataSource(file.getAbsolutePath()); mMediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { // from class: com.XiaoLian.Util.100000000 @Override // android.media.MediaPlayer.OnCompletionListener public void onCompletion(MediaPlayer mediaPlayer) { Util.stopPlay(); } }); mMediaPlayer.setOnErrorListener(new MediaPlayer.OnErrorListener() { // from class: com.XiaoLian.Util.100000001 @Override // android.media.MediaPlayer.OnErrorListener public boolean onError(MediaPlayer mediaPlayer, int i, int i2) { Util.stopPlay(); return true; } }); mMediaPlayer.setVolume((float) 1, (float) 1); mMediaPlayer.setLooping(false); mMediaPlayer.prepare(); mMediaPlayer.start(); } catch (IOException | RuntimeException e) { e.printStackTrace(); stopPlay(); } } public static void stopPlay() { if (mMediaPlayer != null) { mMediaPlayer.setOnCompletionListener(null); mMediaPlayer.setOnErrorListener(null); mMediaPlayer.stop(); mMediaPlayer.reset(); mMediaPlayer.release(); mMediaPlayer = null; } } public static void copyFileUsingFileStreams(File file, File file2) throws IOException { InputStream inputStream = null; OutputStream outputStream = null; try { inputStream = new FileInputStream(file); outputStream = new FileOutputStream(file2); byte[] bArr = new byte[1024]; while (true) { int read = inputStream.read(bArr); if (read != -1) { outputStream.write(bArr, 0, read); } else { return; } } } finally { inputStream.close(); outputStream.close(); } } public static Bitmap compressImage(Bitmap bitmap, int i, int i2) { int i3 = i2; ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(); bitmap.compress(Bitmap.CompressFormat.JPEG, 80, byteArrayOutputStream); while (byteArrayOutputStream.toByteArray().length / 1024 > i) { i3 -= 10; byteArrayOutputStream.reset(); bitmap.compress(Bitmap.CompressFormat.JPEG, i3, byteArrayOutputStream); } return BitmapFactory.decodeStream(new ByteArrayInputStream(byteArrayOutputStream.toByteArray()), null, null); } } 这些里面有RC4Util类代码么?哪一段是?
最新发布
10-29
crash日志: 08-19 09:26:57.321 13888 14095 F libc : Fatal signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0xb400007300000000 in tid 14095 (initCameraInfo), pid 13888 (om.oplus.camera) 08-19 09:27:02.619 17868 17868 F DEBUG : Process name is com.oplus.camera, uid is 10172, not key_process 08-19 09:27:02.620 17868 17868 F DEBUG : keyProcess: 0 08-19 09:27:02.620 17868 17868 F DEBUG : *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** 08-19 09:27:02.620 17868 17868 F DEBUG : Build fingerprint: 'realme/RMX5253IN/RE644C:15/AP3A.240617.008/V.R4T2.2f4847c-100eb7c-100ecfe:user/release-keys' 08-19 09:27:02.620 17868 17868 F DEBUG : Revision: '0' 08-19 09:27:02.620 17868 17868 F DEBUG : ABI: 'arm64' 08-19 09:27:02.620 17868 17868 F DEBUG : Timestamp: 2025-08-19 09:26:57.959834776+0800 08-19 09:27:02.620 17868 17868 F DEBUG : Process uptime: 91s 08-19 09:27:02.620 17868 17868 F DEBUG : Cmdline: com.oplus.camera 08-19 09:27:02.620 17868 17868 F DEBUG : pid: 13888, tid: 14095, name: initCameraInfo >>> com.oplus.camera <<< 08-19 09:27:02.620 17868 17868 F DEBUG : uid: 10172 08-19 09:27:02.620 17868 17868 F DEBUG : tagged_addr_ctrl: 0000000000000001 (PR_TAGGED_ADDR_ENABLE) 08-19 09:27:02.620 17868 17868 F DEBUG : signal 11 (SIGSEGV), code 2 (SEGV_ACCERR), fault addr 0xb400007300000000 08-19 09:27:02.620 17868 17868 F DEBUG : x0 b400007300000000 x1 0000007315411f6f x2 0000000000000000 x3 00000a3a65636172 08-19 09:27:02.620 17868 17868 F DEBUG : x4 0000000000000000 x5 8080000000000000 x6 feff093964626071 x7 7f7f7f7f7f7f7f7f 08-19 09:27:02.620 17868 17868 F DEBUG : x8 6468d103908d46de x9 6468d103908d46de x10 0000000000000002 x11 00000073b640a028 08-19 09:27:02.620 17868 17868 F DEBUG : x12 0000000000000003 x13 00000075ec9a3398 x14 0000000000000001 x15 0000000000000008 08-19 09:27:02.620 17868 17868 F DEBUG : x16 00000073155315d0 x17 0000007314f364a8 x18 000000000000005a x19 b4000073a5cdde20 08-19 09:27:02.620 17868 17868 F DEBUG : x20 0000000000000000 x21 b400007300000000 x22 b4000073a8c0d100 x23 b4000073a5cddd90 08-19 09:27:02.620 17868 17868 F DEBUG : x24 0000000000000000 x25 00000074404aa140 x26 000000748c428108 x27 000000748c428100 08-19 09:27:02.620 17868 17868 F DEBUG : x28 000000748c428110 x29 000000748c427f60 08-19 09:27:02.620 17868 17868 F DEBUG : lr 0000007314f47720 sp 000000748c427f50 pc 0000007314f364b4 pst 0000000060001000 08-19 09:27:02.620 17868 17868 F DEBUG : 21 total frames 08-19 09:27:02.620 17868 17868 F DEBUG : backtrace: 08-19 09:27:02.620 17868 17868 F DEBUG : #00 pc 00000000000b54b4 /odm/lib64/libXDocProcessSDK.so (xsdk::XDocDetector::~XDocDetector()+12) (BuildId: fc607651bf45e25a3db1441a3a35ff1c435e2a55) 08-19 09:27:02.620 17868 17868 F DEBUG : #01 pc 00000000000c671c /odm/lib64/libXDocProcessSDK.so (xsdk::QuadDetector::Init(unsigned char const*, unsigned long, int)+168) (BuildId: fc607651bf45e25a3db1441a3a35ff1c435e2a55) 08-19 09:27:02.620 17868 17868 F DEBUG : #02 pc 00000000000100fc /odm/lib64/libSuperTextWrapper.so (xnnInitedByByte+116) (BuildId: ae32866688049b7aabb663b359b94fc994d77513) 08-19 09:27:02.620 17868 17868 F DEBUG : #03 pc 000000000001329c /product/lib64/libXDocProcessSDK-jni.so (Java_com_youtu_ocr_docprocess_DocDetector_xnnInitedByByte+88) (BuildId: d3b90c13fb4c862fc9f126b36f9cd89338665a31) 08-19 09:27:02.620 17868 17868 F DEBUG : #04 pc 00000000000c91cc /system/framework/arm64/boot.oat (art_jni_trampoline+124) (BuildId: 8a0148760ce648144175623fdb3235cc5d70660c) 08-19 09:27:02.620 17868 17868 F DEBUG : #05 pc 0000000000782420 /apex/com.android.art/lib64/libart.so (nterp_helper+4016) (BuildId: 4ccb65ae9ac5ad5da3af5a342d5b0b92) 08-19 09:27:02.620 17868 17868 F DEBUG : #06 pc 000000000012b588 /product/app/OplusCamera/OplusCamera.apk (com.oplus.ocs.camera.SuperTextHelper.xnnInitedByByte+4) 08-19 09:27:02.620 17868 17868 F DEBUG : #07 pc 00000000007823c4 /apex/com.android.art/lib64/libart.so (nterp_helper+3924) (BuildId: 4ccb65ae9ac5ad5da3af5a342d5b0b92) 08-19 09:27:02.621 17868 17868 F DEBUG : #08 pc 00000000000a5be2 /product/app/OplusCamera/OplusCamera.apk (com.oplus.camera.feature.sticker.ui.n.run+722) 08-19 09:27:02.621 17868 17868 F DEBUG : #09 pc 00000000007831e4 /apex/com.android.art/lib64/libart.so (nterp_helper+7540) (BuildId: 4ccb65ae9ac5ad5da3af5a342d5b0b92) 08-19 09:27:02.621 17868 17868 F DEBUG : #10 pc 00000000000efede /product/app/OplusCamera/OplusCamera.apk (d6.g$a.run+50) 08-19 09:27:02.621 17868 17868 F DEBUG : #11 pc 0000000000338070 /system/framework/arm64/boot.oat (java.util.concurrent.ThreadPoolExecutor.runWorker+784) (BuildId: 8a0148760ce648144175623fdb3235cc5d70660c) 08-19 09:27:02.621 17868 17868 F DEBUG : #12 pc 0000000000334338 /system/framework/arm64/boot.oat (java.util.concurrent.ThreadPoolExecutor$Worker.run+56) (BuildId: 8a0148760ce648144175623fdb3235cc5d70660c) 08-19 09:27:02.621 17868 17868 F DEBUG : #13 pc 00000000001bb790 /system/framework/arm64/boot.oat (java.lang.Thread.run+64) (BuildId: 8a0148760ce648144175623fdb3235cc5d70660c) 08-19 09:27:02.621 17868 17868 F DEBUG : #14 pc 0000000000368774 /apex/com.android.art/lib64/libart.so (art_quick_invoke_stub+612) (BuildId: 4ccb65ae9ac5ad5da3af5a342d5b0b92) 08-19 09:27:02.621 17868 17868 F DEBUG : #15 pc 0000000000353f24 /apex/com.android.art/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+132) (BuildId: 4ccb65ae9ac5ad5da3af5a342d5b0b92) 08-19 09:27:02.621 17868 17868 F DEBUG : #16 pc 0000000000947748 /apex/com.android.art/lib64/libart.so (art::detail::ShortyTraits<(char)86>::Type art::ArtMethod::InvokeInstance<(char)86>(art::Thread*, art::ObjPtr<art::mirror::Object>, art::detail::ShortyTraits<>::Type...)+60) (BuildId: 4ccb65ae9ac5ad5da3af5a342d5b0b92) 08-19 09:27:02.621 17868 17868 F DEBUG : #17 pc 0000000000636e80 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallback(void*)+1344) (BuildId: 4ccb65ae9ac5ad5da3af5a342d5b0b92) 08-19 09:27:02.621 17868 17868 F DEBUG : #18 pc 0000000000636930 /apex/com.android.art/lib64/libart.so (art::Thread::CreateCallbackWithUffdGc(void*)+8) (BuildId: 4ccb65ae9ac5ad5da3af5a342d5b0b92) 08-19 09:27:02.621 17868 17868 F DEBUG : #19 pc 00000000000a67a4 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+196) (BuildId: b963824e1119e1e9ec07440f1ee81f14) 08-19 09:27:02.621 17868 17868 F DEBUG : #20 pc 0000000000097b20 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64) (BuildId: b963824e1119e1e9ec07440f1ee81f14) android日志: 行 236711: 08-19 09:27:02.215 13888 13888 V OCAM_PreviewExceptionProcessor: prePostPreviewException delay: 5000 行 236711: 08-19 09:27:02.215 13888 13888 V OCAM_PreviewExceptionProcessor: prePostPreviewException delay: 5000 行 237467: 08-19 09:27:02.326 13888 14751 E CameraUnit, Camera2Impl: checkSmaWireStatusAndModuleIdArrived, key does not exist: java.lang.IllegalArgumentException: Could not find tag for key 'com.oplus.double.ois.wirecutoff.detection.sn') 行 238996: 08-19 09:27:02.716 18002 18002 D AEE_AED : Duplicated exception, cnt = 2 行 238997: 08-19 09:27:02.716 18002 18002 D AEE_AED : Last exception time: 1755541196 行 239224: 08-19 09:27:02.749 18002 18002 I AEE_AED : $** *** *** *** *** *** *** *** Exception *** *** *** *** *** *** *** **$ 行 239854: 08-19 09:27:02.888 01383 18049 E ifunc_camsv: [vendor/mediatek/proprietary/hardware/mtkcam/drv/src/isp/isp_6s/imageio/drv/cam/isp_function_camsv.cpp, waitBufReady, line1155] ERROR: [0x9]:, m_buf_cnt(0), waitbufready fail is caused by no enque (waitBufReady){#1155:vendor/mediatek/proprietary/hardware/mtkcam/drv/src/isp/isp_6s/imageio/drv/cam/isp_function_camsv.cpp} 行 240135: 08-19 09:27:02.985 18002 18002 I AEE_AED : Exception Log Time:[Tue Aug 19 09:27:02 CST 2025] [70030.923036] 行 240137: 08-19 09:27:02.985 18002 18002 I AEE_AED : Exception Class: Native (NE) 行 240138: 08-19 09:27:02.985 18002 18002 I AEE_AED : Exception Type: SIGSEGV 行 240145: 08-19 09:27:02.986 18002 18002 I AEE_AED : $** *** *** *** *** *** *** *** Exception *** *** *** *** *** *** *** **$ 行 240337: 08-19 09:27:03.083 01733 18054 W AES : Exception Log handling... 行 240370: 08-19 09:27:03.088 01733 18054 D AES : ExceptionLog: notify aed, process:com.oplus.camera pid:13888 cause:system_app_native_crash 行 240524: 08-19 09:27:03.109 13888 14798 V OCAM_PreviewExceptionProcessor: removePreviewException 行 240524: 08-19 09:27:03.109 13888 14798 V OCAM_PreviewExceptionProcessor: removePreviewException 行 240884: 08-19 09:27:03.252 01733 01883 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 241592: 08-19 09:27:03.623 13888 13888 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 241637: 08-19 09:27:03.631 02552 02552 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 241757: 08-19 09:27:03.695 01383 18049 E ifunc_camsv: [vendor/mediatek/proprietary/hardware/mtkcam/drv/src/isp/isp_6s/imageio/drv/cam/isp_function_camsv.cpp, waitBufReady, line1155] ERROR: [0x9]:, m_buf_cnt(0), waitbufready fail is caused by no enque (waitBufReady){#1155:vendor/mediatek/proprietary/hardware/mtkcam/drv/src/isp/isp_6s/imageio/drv/cam/isp_function_camsv.cpp} 行 241785: 08-19 09:27:03.696 13888 13888 V OCAM_PreviewExceptionProcessor: removePreviewException 行 241785: 08-19 09:27:03.696 13888 13888 V OCAM_PreviewExceptionProcessor: removePreviewException 行 242241: 08-19 09:27:03.765 15375 15375 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 242466: 08-19 09:27:03.821 01733 01887 D callGcDesupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 242477: 08-19 09:27:03.824 02276 02276 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 243654: 08-19 09:27:04.292 15375 15375 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 243662: 08-19 09:27:04.298 02276 02276 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 243671: 08-19 09:27:04.307 13888 13888 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 243692: 08-19 09:27:04.322 02552 02552 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 243871: 08-19 09:27:04.443 02552 02552 D OplusGcSupressionExtImpl: callGcSupression : java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 243902: 08-19 09:27:04.451 02552 02552 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 243912: 08-19 09:27:04.452 02552 02552 D OplusGcSupressionExtImpl: callGcDesupression : java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 244302: 08-19 09:27:04.713 18094 18094 D OplusActivityThreadExtImpl: java.lang.NoSuchMethodException: dalvik.system.VMRuntime.SupressionGC [int, int] 行 244306: zv69jrUu7c:0 android.view.InsetsAnimationThreadControlRunner$1$$ExternalSyntheticLambda1.run:0 android.os.Handler.handleCallback:995 android.os.Handler.dispatchMessage:105 android.os.Looper.loopOnce:288 android.os.Looper.loop:393 com.android.launcher.monitor.exception.MainThreadExceptionMonitor.startWatching$lambda$2:15 com.android.launcher.monitor.exception.MainThreadExceptionMonitor.gda:1 行 244306: .view.InsetsAnimationThreadControlRunner$1$$ExternalSyntheticLambda1.run:0 android.os.Handler.handleCallback:995 android.os.Handler.dispatchMessage:105 android.os.Looper.loopOnce:288 android.os.Looper.loop:393 com.android.launcher.monitor.exception.MainThreadExceptionMonitor.startWatching$lambda$2:15 com.android.launcher.monitor.exception.MainThreadExceptionMonitor.gda:1 行 244306: :0 android.os.Handler.handleCallback:995 android.os.Handler.dispatchMessage:105 android.os.Looper.loopOnce:288 android.os.Looper.loop:393 com.android.launcher.monitor.exception.MainThreadExceptionMonitor.startWatching$lambda$2:15 com.android.launcher.monitor.exception.MainThreadExceptionMonitor.gda:1 行 244306: r.handleCallback:995 android.os.Handler.dispatchMessage:105 android.os.Looper.loopOnce:288 android.os.Looper.loop:393 com.android.launcher.monitor.exception.MainThreadExceptionMonitor.startWatching$lambda$2:15 com.android.launcher.monitor.exception.MainThreadExceptionMonitor.gda:1 行 244340: 08-19 09:27:04.769 13888 13888 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 行 244363: 08-19 09:27:04.784 18094 18110 D OplusAppHeapManager: java.lang.NoSuchMethodException: dalvik.system.VMRuntime.updateProcessValue [int, int, int] 行 244409: 08-19 09:27:04.800 18094 18094 D callGcSupression: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object java.lang.reflect.Method.invoke(java.lang.Object, java.lang.Object[])' on a null object reference 请排查问题
09-05
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值