NDK中使用pthread多線程中自己寫的一個BUG

来源:http://www.cnblogs.com/willhua/archive/2017/04/16/6718884.html
-Advertisement-
Play Games

在使用pthread進行NDK中的多線程開發時,自己寫了一個BUG, 這個是啟動函數,即相當於Java中的Thread的run方法。初一看沒啥問題,編譯也能過,APP也能跑,但是每次都會crash。我把crash線程的log貼出來如下: 從log中看出,是記憶體訪問錯誤,然後使用addr2line工具 ...


  在使用pthread進行NDK中的多線程開發時,自己寫了一個BUG,

 1 void *darkGrayThread(void *args)
 2 {
 3     ThreadParam *param = (ThreadParam *)args;
 4     LOG("start%d   end%d   ", param->start, param->end);
 5     int end = param->end;
 6     for(int i = param->start, j = i * 4; i < end; ++i, j+=4)
 7     {
 8         LOG("d1");
 9         param->r[i] = param->rgba[j];
10         param->g[i] = param->rgba[j + 1];
11         param->b[i] = param->rgba[j + 2];
12         LOG("d2  %d    end%d", i, param->end);
13         param->dark[i] = MINT(param->rgba[j], param->rgba[j + 1], param->rgba[j + 2]);
14         param->gray[i] = (UCHAR)((param->rgba[j] * 1224 + param->rgba[j + 1] * 2404 +param->rgba[j + 2] * 467) >> 12);
15         LOG("d3");
16     }
17 }

  這個是啟動函數,即相當於Java中的Thread的run方法。初一看沒啥問題,編譯也能過,APP也能跑,但是每次都會crash。我把crash線程的log貼出來如下:

 1 04-16 14:28:31.577 27602 28062 D MyJni   : d2  2087309    end2073600
 2 04-16 14:28:31.637 27602 28062 D MyJni   : d3
 3 04-16 14:28:31.641 27602 28062 D MyJni   : d3
 4 04-16 14:28:31.641 27602 28062 D MyJni   : d1
 5 04-16 14:28:31.641 27602 28062 D MyJni   : d2  2087552    end2073600
 6 04-16 14:28:31.642 27602 28062 D MyJni   : d3
 7 04-16 14:28:31.642 27602 28062 D MyJni   : d1
 8 04-16 14:28:31.642 27602 28062 D MyJni   : d1
 9 04-16 14:28:31.642 27602 28062 D MyJni   : d2  2087567    end2073600
10 04-16 14:28:31.642 27602 28062 D MyJni   : d3
11 04-16 14:28:31.642 27602 28062 D MyJni   : d3
12 04-16 14:28:31.785 27602 28062 D MyJni   : d2  2089380    end2073600
13 04-16 14:28:31.785 27602 28062 D MyJni   : d3
14 04-16 14:28:31.785 27602 28062 D MyJni   : d1
15 04-16 14:28:31.786 27602 28062 D MyJni   : d1
16 04-16 14:28:31.786 27602 28062 D MyJni   : d2  2089401    end2073600
17 04-16 14:28:31.786 27602 28062 D MyJni   : d2  2089402    end2073600
18 04-16 14:28:31.786 27602 28062 D MyJni   : d3
19 04-16 14:28:31.786 27602 28062 D MyJni   : d2  2089404    end2073600
20 04-16 14:28:32.339 27602 28062 F libc    : Fatal signal 11 (SIGSEGV), code 1, fault addr 0xc6800000 in tid 28062 (Thread-4)
21 04-16 14:28:32.339 27602 28062 F libc    : Fatal signal 11 (SIGSEGV), code 1, fault addr 0xc6800000 in tid 28062 (Thread-4)
22 04-16 14:28:32.340   454   454 W         : debuggerd: handling request: pid=27602 uid=10129 gid=10129 tid=28062
23 04-16 14:28:32.381 28088 28088 F DEBUG   : pid: 27602, tid: 28062, name: Thread-4  >>> com.willhua.opencvstudy <<<
24 04-16 14:28:32.381 28088 28088 F DEBUG   : signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xc6800000
25 04-16 14:28:32.381 28088 28088 F DEBUG   :     r0 000000a7  r1 c6600000  r2 cac6ef0e  r3 000000be
26 04-16 14:28:32.381 28088 28088 F DEBUG   :     r4 caa4ca9c  r5 00200000  r6 00000964  r7 c62038f8
27 04-16 14:28:32.381 28088 28088 F DEBUG   :     r8 00800002  r9 000001d3  sl cac6ef0e  fp cac6ebe0
28 04-16 14:28:32.381 28088 28088 F DEBUG   :     ip c7680000  sp c62038e8  lr caa8e93f  pc caa8e99a  cpsr 200f0030
29 04-16 14:28:32.383 28088 28088 F DEBUG   : 
30 04-16 14:28:32.383 28088 28088 F DEBUG   : backtrace:
31 04-16 14:28:32.383 28088 28088 F DEBUG   :     #00 pc 0004099a  /data/app/com.willhua.opencvstudy-2/lib/arm/libOpenCV.so (_Z14darkGrayThreadPv+209)
32 04-16 14:28:32.383 28088 28088 F DEBUG   :     #01 pc 000475d3  /system/lib/libc.so (_ZL15__pthread_startPv+22)
33 04-16 14:28:32.383 28088 28088 F DEBUG   :     #02 pc 00019d3d  /system/lib/libc.so (__start_thread+6)

  從log中看出,是記憶體訪問錯誤,然後使用addr2line工具定位到是上述代碼中的第13行。

  再仔細一點可以看到,log中列印的end都比前面的數字小!!!上面不是有for迴圈的條件語句嗎?怎麼會出現這種情況!?其中的MINT只是我使用define定義的求三個數中的最小數的巨集。

  為了確定問題,我把13寫成了

1  UCHAR uu = MINT(param->rgba[j], param->rgba[j + 1], param->rgba[j + 2]);
2  param->dark[i] = uu;

  然後根據log分析,還是param->dark[i] = uu; 這行報錯。然後我又跑去前面的代碼確定給dark分配的記憶體沒有問題。還是沒找到原因。

  後面突然發現,寫的darkGrayThread沒有寫返回值!於是趕緊再後面添加一句return (void *)0; 再測試,發現沒問題,原因就是這個了。

  為了知道原因,我在沒有寫return的版本的最後添加LOG("endend"); 發現每次都會有數量不等的endend日誌列印出來。這說明for的條件語句還是有退出迴圈的作用的。

  要想繼續分析,可能需要對比有沒有return的兩個版本的彙編代碼,來比較一下有沒有return他們翻譯成彙編的區別,待後續分析。

  這個問題的收穫就是:寫啟動程式一定記得有return語句,即使你的return值沒有用!

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 之前的某次番嗇看到油管上有這麼一個進度條,當時覺得挺好玩,一直想著做一個試試,剛纔弄了一下寫了一個不算太好看的簡陋版本,哈哈。 (本博客刷新會頭部會出現,因為並沒有真正的參與到瀏覽器載入是否完整這個渲染過程中來,所以只是一個表象,並不是說這個顯示完了就瀏覽器也載入完了所以資源。) ...
  • 一、簡介及安裝: gulp是前端開發過程中對代碼進行構建的工具,是自動化項目的構建利器;她不僅能對網站資源進行優化,而且在開發過程中很多重覆的任務能夠使用正確的工具自動完成;使用她,我們不僅可以很愉快的編寫代碼,而且大大提高我們的工作效率 gulp的優點:基於流的操作、任務化。 常用api:src ...
  • 雪花飄落的效果實現步驟:1.使用setInterval定時器每800毫秒創建一個雪花;2.把每一個雪花作為參數傳進動態下落的方法中即可。 js實現代碼: 效果圖如下: 這樣雪花飄落的效果就做好了。有什麼不足的地方請指正! ...
  • 在上一篇文章《iOS之ProtocolBuffer搭建和示例demo》分享環境的搭建, 我們和伺服器進行IM通訊用了github有名的框架CocoaAsynSocket, 然後和伺服器之間的數據媒介是ProtoBuf。然後後面在開發的過程中也碰到了拆包和粘包問題,這方面網上資料很少,曲折了一下才解決 ...
  • Android保持屏幕常亮,PowerManager.WakeLock的使用 需要在AndroidManifest.xml中添加許可權<uses-permission android:name="android.permission.WAKE_LOCK"/> SCREEN_BRIGHT_WAKE_LO ...
  • 在使用一些產品列如微信、QQ之類的,如果有新消息來時,手機屏幕即使在鎖屏狀態下也會亮起並提示聲音,這時用戶就知道有新消息來臨了。但是,一般情況下手機鎖屏後,Android系統為了省電以及減少CPU消耗,在一段時間後會使系統進入休眠狀態,這時,Android系統中CPU會保持在一個相對較低的功耗狀態。 ...
  • 第一步: 為mac電腦配置 adb 命令的環境變數,分為2小步 1.找到 Android Studio 為你安裝的 SDK : 打開電腦中 Android studio 的工具的軟體,在啟動 Android studio 的軟體的界面中,點擊下方列表中的”configure“的選項。在點擊列表中的“ ...
  • 轉載請註明出處:http://www.cnblogs.com/cnwutianhao/p/6719380.html 作為Android開發者,一定不會對 GreenDao 和 ReactiveX 陌生。 GreenDao 號稱Android最快的關係型資料庫 ReactiveX Rx是一個編程模型, ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...