Android 10 SurfaceView 奔溃报错signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4
最近在Android 10 系统上发现SurfaceView 测试的时候奔溃了,10以前的系统测试都会奔溃,在Android 11之后的设备上是正常的。
上错误日志
Native 报错信息
signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4
Cause: null pointer dereferenceeax 00000000 ebx f017756c ecx 00000001 edx 00017af6edi 00017af6 esi edbe9140ebp c4c67938 esp c4c67920 eip f0169a71backtrace:#00 pc 0000fa71 /system/lib/libutils.so (android::RefBase::incStrong(void const*) const+33) (BuildId: 288ba3aff5b46dbd7e74be954af88b83)#01 pc 00114620 /system/lib/libandroid_runtime.so (android::nativeDeferTransactionUntilSurface(_JNIEnv*, _jclass*, long long, long long, long long, long long)+96) (BuildId: 3643bee2c4fb7899d7781c565843060b)#02 pc 002a2325 /system/framework/x86/boot-framework.oat (art_jni_trampoline+213) (BuildId: 38176ebc9c3cce5f657a723b08d40d487952c484)#03 pc 0204d399 /memfd:/jit-cache (deleted) (android.view.SurfaceControl.access$2700+89)#04 pc 020421aa /memfd:/jit-cache (deleted) (android.view.SurfaceControl$Transaction.deferTransactionUntilSurface+202)#05 pc 02036db1 /memfd:/jit-cache (deleted) (android.view.SurfaceView.applySurfaceTransforms+177)#06 pc 0204979f /memfd:/jit-cache (deleted) (android.view.SurfaceView.setParentSpaceRectangle+95)#07 pc 020546cb /memfd:/jit-cache (deleted) (android.view.SurfaceView.access$200+59)#08 pc 0204ae12 /memfd:/jit-cache (deleted) (android.view.SurfaceView$3.positionChanged+434)#09 pc 0203c004 /memfd:/jit-cache (deleted) (android.graphics.RenderNode$CompositePositionUpdateListener.positionChanged+148)
应用层log看到的错误信息
Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x10 in tid 6711 (hwuiTask0), pid 6669 (.crash)
Exception from repositionChildjava.lang.NullPointerException: mNativeObject is null. Have you called release() already?at android.view.SurfaceControl.checkNotReleased(SurfaceControl.java:945)at android.view.SurfaceControl.access$800(SurfaceControl.java:77)at android.view.SurfaceControl$Transaction.setPosition(SurfaceControl.java:2170)at android.view.SurfaceView.applySurfaceTransforms(SurfaceView.java:1025)at android.view.SurfaceView.setParentSpaceRectangle(SurfaceView.java:1038)at android.view.SurfaceView.access$200(SurfaceView.java:99)at android.view.SurfaceView$1.positionChanged(SurfaceView.java:1081)
根据报错的信息在网上查找到相关的一个google patch
commit 005c63e8c6e6e5b312dc9c4631c57fb12224df30 [log] [tgz]
author Robert Carr <racarr@google.com> Fri Sep 20 14:31:24 2019 -0700
committer Robert Carr <racarr@google.com> Fri Sep 20 14:48:40 2019 -0700
tree 939eaeca0159a44bca7b5abf44f41f5096c1fb90
parent c48da419931a3a9272910f2631f815cecf05c9ba [diff]
SurfaceView: Destroy SurfaceControl from RenderThreadCurrently there is a race where the UI thread can destroy
the SurfaceControl (free the C++ object) while the RenderThread
still has pending operations on it. To fix have the positionLost callback handle the destruction.Bug: 139111930
Bug: 136808018
Test: go/wm-smoke
Change-Id: Id5225e1e47046d928f8298de38ff61662debe360
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 90e69f3..262b9e5 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -136,6 +136,7 @@@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)boolean mIsCreating = false;private volatile boolean mRtHandlingPositionUpdates = false;
+ private volatile boolean mRtReleaseSurfaces = false;private final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener =this::updateSurface;
@@ -658,7 +659,14 @@}private void releaseSurfaces() {
+ mSurfaceAlpha = 1f;
+synchronized (mSurfaceControlLock) {
+ if (mRtHandlingPositionUpdates) {
+ mRtReleaseSurfaces = true;
+ return;
+ }
+if (mSurfaceControl != null) {mTmpTransaction.remove(mSurfaceControl);mSurfaceControl = null;
@@ -669,7 +677,6 @@}mTmpTransaction.apply();}
- mSurfaceAlpha = 1f;}/** @hide */
@@ -1084,7 +1091,9 @@// the synchronization would violate the rule that RT must never block// on the UI thread which would open up potential deadlocks. The risk of// a single-frame desync is therefore preferable for now.
- mRtHandlingPositionUpdates = true;
+ synchronized(mSurfaceControlLock) {
+ mRtHandlingPositionUpdates = true;
+ }if (mRTLastReportedPosition.left == left&& mRTLastReportedPosition.top == top&& mRTLastReportedPosition.right == right
@@ -1126,6 +1135,18 @@frameNumber);}mRtTransaction.hide(mSurfaceControl);
+
+ synchronized (mSurfaceControlLock) {
+ if (mRtReleaseSurfaces) {
+ mRtReleaseSurfaces = false;
+ mRtTransaction.remove(mSurfaceControl);
+ mRtTransaction.remove(mBackgroundControl);
+ mSurfaceControl = null;
+ mBackgroundControl = null;
+ }
+ mRtHandlingPositionUpdates = false;
+ }
+mRtTransaction.apply();}};
更新后SurfaceView getViewRootImpl()会经常为空。找不到其他更新的patch。
因为在Android11 上测试是正常的,所以Android11 是解决了这个问题的,所以直接抄Android11 的SurfaceView的代码。因为Android11 更新了很多东西,所以挑相关的修改进行更新。
diff --git a/frameworks/base/core/java/android/view/SurfaceView.java b/frameworks/base/core/java/android/view/SurfaceView.java
index d11548d687..3d1a5a3549 100644
--- a/frameworks/base/core/java/android/view/SurfaceView.java
+++ b/frameworks/base/core/java/android/view/SurfaceView.java
@@ -118,8 +118,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallbboolean mDrawFinished = false;final Rect mScreenRect = new Rect();
- SurfaceSession mSurfaceSession;
-
+ private final SurfaceSession mSurfaceSession = new SurfaceSession();SurfaceControl mSurfaceControl;// In the case of format changes we switch out the surface in-place// we need to preserve the old one until the new one has drawn.
@@ -135,6 +134,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)boolean mIsCreating = false;private volatile boolean mRtHandlingPositionUpdates = false;
+ private volatile boolean mRtReleaseSurfaces = false;private final ViewTreeObserver.OnScrollChangedListener mScrollChangedListener =this::updateSurface;
@@ -428,9 +428,16 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb}private void performDrawFinished() {
+ if (mDeferredDestroySurfaceControl != null) {
+ synchronized (mSurfaceControlLock) {
+ mTmpTransaction.remove(mDeferredDestroySurfaceControl).apply();
+ mDeferredDestroySurfaceControl = null;
+ }
+ }if (mPendingReportDraws > 0) {mDrawFinished = true;if (mAttachedToWindow) {
+ mParent.requestTransparentRegion(SurfaceView.this);notifyDrawFinished();invalidate();}
@@ -658,7 +665,15 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb}private void releaseSurfaces() {
+ mSurfaceAlpha = 1f;
+synchronized (mSurfaceControlLock) {
+ mSurface.release();
+ if (mRtHandlingPositionUpdates) {
+ mRtReleaseSurfaces = true;
+ return;
+ }
+if (mSurfaceControl != null) {mTmpTransaction.remove(mSurfaceControl);mSurfaceControl = null;
@@ -669,7 +684,6 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb}mTmpTransaction.apply();}
- mSurfaceAlpha = 1f;}/** @hide */
@@ -680,12 +694,21 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb}return;}
- ViewRootImpl viewRoot = getViewRootImpl();
- if (viewRoot == null || viewRoot.mSurface == null || !viewRoot.mSurface.isValid()) {
+ final ViewRootImpl viewRoot = getViewRootImpl();
+ if (viewRoot == null) {
+ if (DEBUG) {
+ Log.d(TAG, System.identityHashCode(this)
+ + " updateSurface: viewRoot null");
+ }
+ return;
+ }
+ if (viewRoot.mSurface == null || !viewRoot.mSurface.isValid()) {if (DEBUG) {Log.d(TAG, System.identityHashCode(this)+ " updateSurface: no valid surface");}
+ notifySurfaceDestroyed();
+ releaseSurfaces();return;}@@ -708,9 +731,14 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallbfinal boolean sizeChanged = mSurfaceWidth != myWidth || mSurfaceHeight != myHeight;final boolean windowVisibleChanged = mWindowVisibility != mLastWindowVisibility;boolean redrawNeeded = false;
-
- if (creating || formatChanged || sizeChanged || visibleChanged || (mUseAlpha
- && alphaChanged) || windowVisibleChanged) {
+ getLocationInSurface(mLocation);
+ final boolean positionChanged = mWindowSpaceLeft != mLocation[0]
+ || mWindowSpaceTop != mLocation[1];
+ final boolean layoutSizeChanged = getWidth() != mScreenRect.width()
+ || getHeight() != mScreenRect.height();
+ if (creating || formatChanged || sizeChanged || visibleChanged ||
+ (mUseAlpha && alphaChanged) || windowVisibleChanged ||
+ positionChanged || layoutSizeChanged) {getLocationInWindow(mLocation);if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
@@ -744,7 +772,6 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallbif (creating) {viewRoot.createBoundsSurface(mSubLayer);
- mSurfaceSession = new SurfaceSession();mDeferredDestroySurfaceControl = mSurfaceControl;updateOpaqueFlag();
@@ -853,28 +880,7 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallbfinal boolean surfaceChanged = creating;if (mSurfaceCreated && (surfaceChanged || (!visible && visibleChanged))) {mSurfaceCreated = false;
- if (mSurface.isValid()) {
- if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
- + "visibleChanged -- surfaceDestroyed");
- callbacks = getSurfaceCallbacks();
- for (SurfaceHolder.Callback c : callbacks) {
- c.surfaceDestroyed(mSurfaceHolder);
- }
- // Since Android N the same surface may be reused and given to us
- // again by the system server at a later point. However
- // as we didn't do this in previous releases, clients weren't
- // necessarily required to clean up properly in
- // surfaceDestroyed. This leads to problems for example when
- // clients don't destroy their EGL context, and try
- // and create a new one on the same surface following reuse.
- // Since there is no valid use of the surface in-between
- // surfaceDestroyed and surfaceCreated, we force a disconnect,
- // so the next connect will always work if we end up reusing
- // the surface.
- if (mSurface.isValid()) {
- mSurface.forceScopedDisconnect();
- }
- }
+ notifySurfaceDestroyed();}if (creating) {
@@ -933,7 +939,6 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb} finally {mIsCreating = false;if (mSurfaceControl != null && !mSurfaceCreated) {
- mSurface.release();releaseSurfaces();}}
@@ -944,48 +949,6 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallbTAG, "Layout: x=" + mScreenRect.left + " y=" + mScreenRect.top+ " w=" + mScreenRect.width() + " h=" + mScreenRect.height()+ ", frame=" + mSurfaceFrame);
- } else {
- // Calculate the window position in case RT loses the window
- // and we need to fallback to a UI-thread driven position update
- getLocationInSurface(mLocation);
- final boolean positionChanged = mWindowSpaceLeft != mLocation[0]
- || mWindowSpaceTop != mLocation[1];
- final boolean layoutSizeChanged = getWidth() != mScreenRect.width()
- || getHeight() != mScreenRect.height();
- if (positionChanged || layoutSizeChanged) { // Only the position has changed
- mWindowSpaceLeft = mLocation[0];
- mWindowSpaceTop = mLocation[1];
- // For our size changed check, we keep mScreenRect.width() and mScreenRect.height()
- // in view local space.
- mLocation[0] = getWidth();
- mLocation[1] = getHeight();
-
- mScreenRect.set(mWindowSpaceLeft, mWindowSpaceTop,
- mWindowSpaceLeft + mLocation[0], mWindowSpaceTop + mLocation[1]);
-
- if (translator != null) {
- translator.translateRectInAppWindowToScreen(mScreenRect);
- }
-
- if (mSurfaceControl == null) {
- return;
- }
-
- if (!isHardwareAccelerated() || !mRtHandlingPositionUpdates) {
- try {
- if (DEBUG_POSITION) {
- Log.d(TAG, String.format("%d updateSurfacePosition UI, "
- + "position = [%d, %d, %d, %d]",
- System.identityHashCode(this),
- mScreenRect.left, mScreenRect.top,
- mScreenRect.right, mScreenRect.bottom));
- }
- setParentSpaceRectangle(mScreenRect, -1);
- } catch (Exception ex) {
- Log.e(TAG, "Exception configuring surface", ex);
- }
- }
- }}}@@ -994,12 +957,6 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallbLog.i(TAG, System.identityHashCode(this) + " "+ "finishedDrawing");}
-
- if (mDeferredDestroySurfaceControl != null) {
- mTmpTransaction.remove(mDeferredDestroySurfaceControl).apply();
- mDeferredDestroySurfaceControl = null;
- }
-runOnUiThread(this::performDrawFinished);}@@ -1015,9 +972,8 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb}private void applySurfaceTransforms(SurfaceControl surface, Rect position, long frameNumber) {
- if (frameNumber > 0) {
- final ViewRootImpl viewRoot = getViewRootImpl();
-
+ final ViewRootImpl viewRoot = getViewRootImpl();
+ if (frameNumber > 0 && viewRoot != null ) {mRtTransaction.deferTransactionUntilSurface(surface, viewRoot.mSurface,frameNumber);}
@@ -1036,10 +992,10 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallbfinal ViewRootImpl viewRoot = getViewRootImpl();applySurfaceTransforms(mSurfaceControl, position, frameNumber);
-
- applyChildSurfaceTransaction_renderWorker(mRtTransaction, viewRoot.mSurface,
+ if (frameNumber > 0 && viewRoot != null ) {
+ applyChildSurfaceTransaction_renderWorker(mRtTransaction, viewRoot.mSurface,frameNumber);
-
+ }mRtTransaction.apply();}@@ -1062,7 +1018,9 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallb// the synchronization would violate the rule that RT must never block// on the UI thread which would open up potential deadlocks. The risk of// a single-frame desync is therefore preferable for now.
- mRtHandlingPositionUpdates = true;
+ synchronized(mSurfaceControlLock) {
+ mRtHandlingPositionUpdates = true;
+ }if (mRTLastReportedPosition.left == left&& mRTLastReportedPosition.top == top&& mRTLastReportedPosition.right == right
@@ -1096,14 +1054,27 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallbif (mSurfaceControl == null) {return;}
+ final ViewRootImpl viewRoot = getViewRootImpl();- if (frameNumber > 0) {
- final ViewRootImpl viewRoot = getViewRootImpl();- mRtTransaction.deferTransactionUntilSurface(mSurfaceControl, viewRoot.mSurface,
- frameNumber);
+ synchronized (mSurfaceControlLock) {
+ if (frameNumber > 0 && viewRoot != null) {
+ if (viewRoot.mSurface.isValid()) {
+ mRtTransaction.deferTransactionUntilSurface(mSurfaceControl, viewRoot.mSurface,
+ frameNumber);
+ }
+ }
+ mRtTransaction.hide(mSurfaceControl);
+ if (mRtReleaseSurfaces) {
+ mRtReleaseSurfaces = false;
+ mRtTransaction.remove(mSurfaceControl);
+ mRtTransaction.remove(mBackgroundControl);
+ mSurfaceControl = null;
+ mBackgroundControl = null;
+ }
+ mRtHandlingPositionUpdates = false;}
- mRtTransaction.hide(mSurfaceControl);
+mRtTransaction.apply();}};
@@ -1348,4 +1319,29 @@ public class SurfaceView extends View implements ViewRootImpl.WindowStoppedCallbpublic SurfaceControl getSurfaceControl() {return mSurfaceControl;}
+
+ private void notifySurfaceDestroyed() {
+ if (mSurface.isValid()) {
+ if (DEBUG) Log.i(TAG, System.identityHashCode(this) + " "
+ + "surfaceDestroyed");
+ SurfaceHolder.Callback[] callbacks = getSurfaceCallbacks();
+ for (SurfaceHolder.Callback c : callbacks) {
+ c.surfaceDestroyed(mSurfaceHolder);
+ }
+ // Since Android N the same surface may be reused and given to us
+ // again by the system server at a later point. However
+ // as we didn't do this in previous releases, clients weren't
+ // necessarily required to clean up properly in
+ // surfaceDestroyed. This leads to problems for example when
+ // clients don't destroy their EGL context, and try
+ // and create a new one on the same surface following reuse.
+ // Since there is no valid use of the surface in-between
+ // surfaceDestroyed and surfaceCreated, we force a disconnect,
+ // so the next connect will always work if we end up reusing
+ // the surface.
+ if (mSurface.isValid()) {
+ mSurface.forceScopedDisconnect();
+ }
+ }
+ }}
经过修改后,测试是正常了,应用不会奔溃,就是时不时冒出一个Error的log信息
E/Layer: [SurfaceView - com.crash/com.crash.MainActivity#3] No local sync point found
查看Layer.cpp 遇到这种异常的时候是跳过逻辑的,所以就不管了,目前还不清楚这样改有没有其他什么问题。
741 bool Layer::applyPendingStates(State* stateToCommit) {742 bool stateUpdateAvailable = false;743 while (!mPendingStates.empty()) {744 if (mPendingStates[0].barrierLayer_legacy != nullptr) {745 if (mRemoteSyncPoints.empty()) {746 // If we don't have a sync point for this, apply it anyway. It747 // will be visually wrong, but it should keep us from getting748 // into too much trouble.749 ALOGE("[%s] No local sync point found", mName.string());750 popPendingState(stateToCommit);751 stateUpdateAvailable = true;752 continue;753 }754755 if (mRemoteSyncPoints.front()->getFrameNumber() !=756 mPendingStates[0].frameNumber_legacy) {757 ALOGE("[%s] Unexpected sync point frame number found", mName.string());758759 // Signal our end of the sync point and then dispose of it760 mRemoteSyncPoints.front()->setTransactionApplied();761 mRemoteSyncPoints.pop_front();762 continue;763 }764765 if (mRemoteSyncPoints.front()->frameIsAvailable()) {766 ATRACE_NAME("frameIsAvailable");767 // Apply the state update768 popPendingState(stateToCommit);769 stateUpdateAvailable = true;770771 // Signal our end of the sync point and then dispose of it772 mRemoteSyncPoints.front()->setTransactionApplied();773 mRemoteSyncPoints.pop_front();774 } else {775 ATRACE_NAME("!frameIsAvailable");776 break;777 }778 } else {779 popPendingState(stateToCommit);780 stateUpdateAvailable = true;781 }782 }783784 // If we still have pending updates, wake SurfaceFlinger back up and point785 // it at this layer so we can process them786 if (!mPendingStates.empty()) {787 setTransactionFlags(eTransactionNeeded);788 mFlinger->setTransactionFlags(eTraversalNeeded);789 }790791 mCurrentState.modified = false;792 return stateUpdateAvailable;793 }
Android 10 SurfaceView 奔溃报错signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x4相关推荐
- cn.sample.mnn.detect A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 in tid
mnn报错: cn.sample.mnn.detect A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x0 ...
- 游戏测试问题之:Caused by: java.lang.Error: signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 00000004
公司开发的小游戏在进行 Monkey 测试时在个别机型一直遇到相同的几个问题,特此记录一下 错误日志如下: Caused by: java.lang.Error: signal 11 (SIGSEGV ...
- A/libc:fatal signal 11(SIGSEGV).code 1, fault addr 0x0 in tid 26488 (VideoEncoder)
在调试Camera模块:发现相同的代码在厂家提供的环境里边编译.就是ok的,在我们的源码树中编译,将HAL库推进去后.就会signal 11退出. 一.现象 1 F/libc ( 4250): Fat ...
- Fatal signal 11 (SIGSEGV), code 1, fault addr 0x10457e30d996b in tid 5676 (ndroid.settings)
FROM:http://blogold.chinaunix.net/u3/104564/showart_2091186.html 一.安装交叉编译器 1)交叉编译器使用CodeSourcery提供的 ...
- signal 11 (SIGSEGV), code 2 (SEGV_ACCERR)的原因和解决办法
码字不易,转载请注明出处喔 https://blog.csdn.net/newchenxf/article/details/121537539 1 结论 可能你打开这篇文章,是在某个加班的深夜,时间真 ...
- Android JNI 报错(signal 6 (SIGABRT), code -1 (SI_QUEUE), fault addr )
目前看是线程调用问题引起的 , 错误Log如下: F DEBUG : uid: 1000 F DEBUG : signal 6 (SIGABRT), code -1 (SI_QUEUE), fault ...
- Android NDK thread 回收crash, signal 4 (SIGILL), code 1 (ILL_ILLOPC) , fault addr 地址
Android NDK thread 回收crash, signal 4 (SIGILL), code 1 (ILL_ILLOPC) , fault addr 地址 在NDK c++ 使用pthrea ...
- JNI中Fatal signal 11 (SIGSEGV), code 1的错误.
这个错,搞了一天才搞定.还是自己对jni不熟. com.viking.myapplication A/libc: Fatal signal 11 (SIGSEGV), code 1, fault ad ...
- 【我的C/C++语言学习进阶之旅】NDK开发之解决错误:signal 5 (SIGTRAP), code 1 (TRAP_BRKPT), fault addr 0xXXX
一.错误描述 今天在使用C++实现一个OpenGL特效的时候,运行出错,如下所示: 错误描述为: signal 5 (SIGTRAP), code 1 (TRAP_BRKPT), fault addr ...
最新文章
- Java源码详解二:HashMap源码分析--openjdk java 11源码
- cm 怎么限制hue数据下载_0724-6.2.0-CM接管rpm方式安装的无CM的CDH集群-2
- 对 Jquery 表单插件 Form.js 2.12 的调整
- ios 防止按钮快速点击造成多次响应的避免方法。
- 【Error】IDEA报错:org.jetbrains.jps.builders.java.dependencyView.TypeRepr$PrimitiveType cannot be cast t
- 米的建站日记(2014年12月15日)
- Shiro过滤器配置(ShiroFilterFactoryBean)
- mysql之select+五种子句的理解
- 东京疫情数据开源当日斩获2k+ star,GitHub疫情项目源源不断
- 使用Jackson解析JSON
- params.c:Parameter() - Ignoring badly formed line in configuration file: ignore errors 解决方法
- Linux为硬盘重建MBR,linux重建mbr
- C语言 switch语句来调用函数
- Loongson2f_灵珑9S2A_debian5(lenny)更改国内archive软件源并使用源码编译安装bochs-2.6.9
- 解析button和input type=button 的区别
- 随机的Lazy-Greedy:lazier than lazy greedy
- 微信 8.0 「裂开」「炸弹」的特效代码来了
- 优酷路由宝增加php,优酷路由宝刷入breed教程
- 固高Otostudio软件使用基础知识
- css3摇骰子,css3实现掷骰子(无图)
热门文章
- DVWA V1.9:Reflected Cross Site Scripting(存储型XSS)
- ps2021直装版|ps2021中文直装版 v22.0.0.35附安装教程
- 微信终于出新功能了:自动登录该设备
- 如何正确修改标题,如何修改标题不会被降权?
- win7系统的两种硬盘格式mbr和gpt怎么选择?
- linux ls 目录颜色,改变ls 中目录颜色的方法
- 宝塔linux升级,宝塔linux面板去除后台强制更新
- Ubuntu18.04更换开机登录界面壁纸
- 对于我们大冒险游戏的评论回复
- iPhone的解锁、越狱、激活、固件等等是什么意思,有什么分别?