Linux編程時遇到Oops提示該如何排查?

2021-01-10 電子產品世界

  各位工程師在Linux下開發程序時,有沒有遇到由於系統中存在某些小故障而跳出了「Oops」提示的情況,此時你是如何排查故障?一行行的查看代碼嗎?其實不用那麼複雜,本文將為你介紹一種高效的Linux編程的故障排除方法。

本文引用地址:http://www.eepw.com.cn/article/201811/395128.htm

  在分析Oops之前,我們先來看以下這麼一個例子,使用GPIO的中斷做掉電檢測,參考《嵌入式Linux開發教程下冊》的驅動框架,設計如下程序框圖:

  


  這個框架設計之初的理想流程為:應用啟動->程序初始化->應用open設備->等待中斷事件,但實際項目開發時,往往發生許許多多不可預測的事情。如小王正在調Qt應用,發現老王的進程老在列印,那就不讓老王的進程開機自啟動,調了兩三天後,不定時地提示個Oops提示,小王按照「以前代碼不出現,新加的出現,那麼起因絕對在新代碼內」的慣性思維,認為是新加的Qt導致的,然後小王就不斷測試,不斷查找bug中.......這樣就過去了十年。

  但原因其實是小王沒有open設備,即驅動層沒有初始化定時器隊列,那麼中斷處理函數中50ms觸發的隊列就為一個空值,空指針時Linux內核當然「哎呦」一下提醒你了,而不定時地提示其實就是因為電源不定時地鬆動,gpio檢測到掉電了所以觸發了中斷。

  實際上,這樣的案例十分常見,原本想A->B->C,實際使用是A->D->C,又或者驅動中有某個變量忘記初始化等等,這時分析Oops就可以十分快速地解決問題。那接下來我們就用Linux中標準驅動去觸發一個Oops,對的你沒看錯,Linux內核標準源碼也存在這樣的異常,而且我們也可以去修復這樣的問題。

  使用我司的EasyARM-iMX283開發板,內核源碼為光碟內的Linux-2.6.35.3.tar.bz2,編譯方法請參考光碟資料,我們需要把lcd的背光碟機動修改為ko模式。

  


  燒錄完新內核,加載新編譯出來的drivers/video/backlight/mxs_bl.ko文件就會提示以下Oops信息:

  


  乍看之下,這段信息跟亂碼差不多,但只要你一層層地分析,你就會發現,這些信息已經告訴了我們錯誤的原因。接下來就開始我們的Oops分析之旅。

  1、主要錯誤信息

  


  用於提示錯誤的類型,這裡表示使用空指針。

  2、操作入口

  


  用於提示錯誤的操作,這裡表示加載mxs_bl模塊時出錯,對應於加載操作insmod mxs_bl.ko。

  3、PC指針

  


  用於提示出錯時的PC指針位置,PC指針即當前程序運行點的地址,這裡提示表示錯誤函數為regulator_set_current_limit,偏移地址為0xc。

  4、LR指針

  


  用於提示出錯時的LR指針位置,LR指針即調用子函數的上一個函數名以及入口偏移量,這裡表示上一個函數為set_bl_intensity,偏移地址為0xd8。即set_bl_intensity調用regulator_set_current_limit時出錯。

  5、寄存器值

  


  用於記錄出錯時各個寄存器的值,對於彙編比較熟悉的同志們可以研究一下這段信息。

  6、出錯進程信息

  


  用於提示出錯的進程id號與進程名稱。出錯進程為insmod, PID號2261,對於多任務系統中,可能存在多個PID調用同一個接口的情況。

  7、出錯時的堆棧信息

  


  用於提示出錯時堆棧內保存的寄存器信息,當程序由於中斷發生或子程序調用時,會執行壓棧操作,即將運行環境保存到堆棧內,保證退出中斷或跳出子程序後,運行環境不發生改變。

  而此處的堆棧信息即記錄了程序運行時的環境信息。從中我們可以找到許多LR地址,從而分析出函數調用關係,與下一段的信息有類似作用。

  8、函數執行的回溯關係

  



相關焦點

  • Linux下C編程基礎之:本章小結與思考與練習
    3.8 本章小結本章是Linux中進行C語言編程的基礎,首先講解了C語言編程的關鍵點,這裡關鍵要了解編輯器、編譯連結器、調試器及項目管理工具等概念。
  • Linux下內存洩漏工具
    當以前分配的一片內存不再需要使用或無法訪問時,但是卻並沒有釋放它,這時就出現了內存洩漏。儘管優秀的編程實踐可以確保最少的洩漏,但是根據經驗,當使用大量的函數對相同的內存塊進行處理時,很可能會出現內存洩漏。  內存洩露可以分為以下幾類:  1. 常發性內存洩漏。發生內存洩漏的代碼會被多次執行到,每次被執行的時候都會導致一塊內存洩漏。
  • Linux多線程編程和Linux 2.6下的NPTL
    而多線程編程對於系統程式設計師而言是必須掌握的技術,因此總是讓學習中的程式設計師覺得頭痛不以。我自己也沒有太多多線程編程的經驗,在這裡只是把自己收集到的一些關於Linux上多線程還算新的資料進行匯總來拋磚引玉,以便相互學習交流。
  • 編寫一個簡單的遊戲來練習用 C+編程|Linux 中國
    本文字數:3473,閱讀時長大約:4分鐘 https://linux.cn/article-12985-1.html 作者:Seth Kenlon 譯者:Xingyu.Wang C++ 語言很複雜,但它可以教會你很多關於數據類型
  • Linux安裝軟體時90%的人會遇到這個報錯,如何解決?
    提示 Could not get lock /var/lib/dpkg/lock 報錯?有些小夥伴在使用 apt 包管理器更新或安裝軟體時,可能會遇到過諸如以下的錯誤提示:E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource temporarily unavailable)E: Unable to acquire the dpkg frontend lock (/var/
  • Linux下如何掛載新磁碟:mount
    前言在linux系統伺服器上插了一個U盤,結果系統顯示不出來,是什麼原因導致了系統不能識別U盤呢?經過一番搜索,發現新的硬體設備插在linux系統上時,如果不能正常顯示,則需要通過掛載讓U盤顯示出來,這裡就用到了我們今天要介紹的命令:mount。
  • 計算思維≠編程,該如何培養孩子的計算思維?
    在用計算思維解決問題時,人負責把實際問題轉化為可計算問題,並設計算法讓計算機去執行,計算機負責具體的運算任務,通過運算,達到人想要實現的工作目標,並將這個結果呈現出來,這就是計算思維裡的人機分工。很多人會把計算思維和編程混在一起。計算思維是人大腦的一種思維方式,編程則是人輸入計算機的一種語言運算方式。
  • 海邊遇到離岸流該如何自救?
    海邊遇到離岸流該如何自救?那麼,遇上吃「人」的離岸流如何自救?這段視頻一定要看!離岸流到底是什麼?認清離岸流離岸流又稱裂流,是在海浪和淺灘地形共同作用下,岸邊的一股射束式的強勁水流,多以垂直或接近垂直於岸線的方向回流入海,可將人捲入深水,是海灘溺水事故的最主要原因,可對沿海遊客和群眾頻繁造成生命威脅。
  • 從RTOS到Linux的應用移植
    1 RTOS到Linux的移植分析  幾乎所有的RTOS都有一個簡單的編程模型,它由多線程的執行(通常稱為任務)構成,包含在單一的地址空間中。在RTOS中,單一主程序下多任務同時運行,具有很高的實時響應能力。
  • 從串口驅動到Linux驅動模型,想轉Linux的必會!
    當Windows 10的升級提示從你計算機的右下角彈出時。你可以不假思索的點擊『馬上升級』嗎?我想大多數人對這個問題的答案是否定的。為什麼?因為大多數情況下。升級之後就會變得更卡。延遲更大。一些無用而龐大的軟體瘋狂的佔用你有限的計算機資源。而如果你選擇的是Linux。你幾乎可以任意的在計算機上安裝軟體。運行程序(如果你的內存不是太小。且硬碟交換分區足夠的話)。
  • Linux-Centos下之RabbitMQ快速安裝
    所有主要的程式語言均有與代理接口通訊的客戶端庫。下載Erlang和RabbitMQ安裝包:rlang-21.1-1.el7.centos.x86_64.rpm和rpm -ivh rabbitmq-server-3.7.8-1.el7.noarch.rpm。
  • linux下安裝虛擬機,完美在linux系統下運行通達信軟體
    現在越來越多的人使用linux系統,現在很多的國產作業系統都是基於linux內核上的。雖說不少的軟體都可以運行在linux的系統上。但是對於股票軟體來說在linux上的使用是一個硬傷。能夠運行在linux下的國內股票軟體少之又少。
  • 一張圖看懂Linux內核中Percpu變量的實現
    我們在使用各種程式語言進行多線程編程時,經常會用到thread local變量。但你知道嗎,不僅是在程式語言中,在linux內核中,也有一個類似的機制,用來實現類似的目的,它叫做percpu變量。percpu變量,顧名思義,就是對於同一個變量,每個cpu都有自己的一份,它可以被用來存放一些cpu獨有的數據,比如cpu的id,cpu上正在運行的線程等等,因該機制可以非常方便的解決一些特定問題,所以在內核編程中被廣泛使用。
  • 17 個 Linux 下用於 C/C++ 的最好的 IDE
    ,它能夠提供現代化的、通用的編程功能,可以用於開發包括視頻遊戲、搜尋引擎、其他計算機軟體乃至作業系統等在內的各種大型應用。: https://atom.io/安裝指南: http://www.tecmint.com/atom-text-and-source-code-editor-for-linux
  • 編程短文:Bash echo如何原生輸出帶空格的字符串而不換行
    引言為什麼要數量掌握bash編程,因為它是linux下的默認工具。任何時候與系統內核對話,我們都直接面對shell。作業系統提供了為數眾多的便利工具,用於完成複雜的操作。今天我們說一個最為常用的輸出字符串的指令 echo。
  • Linux 之父拒絕 996,Swift、Python 之父痴迷深夜編程,程式設計師之神...
    Bessarabov <ivan@bessarabov.ru> 1563188141 +0300committer Ivan Bessarabov <ivan@bessarabov.ru> 1563188141 +0300Initial commit從上圖你可以看到提交信息 (Initial commit) 、存儲文件結構的帳號的信息、提交作者的名字和郵件以及最有趣的時戳
  • 國產linux發行版本——deepin作業系統安裝方法
    大家好,歡迎回到萬魔寺,前兩期,和大家一起學習了ubuntu系統的安裝,今天我們一起來學習一下國產linux作業系統deepin的安裝方法。deepin系統是由武漢深之度科技有限公司開發,在網絡上口碑比較好的一款linux國產發行版。
  • 這裡有詳細的應急排查手冊!
    2 排查思路一個常規的入侵事件後的系統排查思路:如果一個用戶有不止一個登錄會話,那他的用戶名把顯示相同的次數    last 命令往回搜索wtmp來顯示自從文件第一次創建以來登錄過的用戶    finger 命令用來查找並顯示用戶信息,系統管理員通過使用該命令可以知道某個時候到底有多少用戶在使用這臺Linux主機。
  • 圖說Java中的OOPs(面向對象編程系統)基本概念
    面向對象編程是一種編程概念,其核心思想是允許用戶創建所需要的對象,然後提供處理這些對象的方法,使用者通過操作對象而獲得運算數據。本文將以簡潔的方式對面向對象編程中的概念進行梳理。1.他是面向對象編程系統(OOPS)的重要組成部分。Java繼承的思想是可以創建基於現有類的新類。從現有類繼承時,可以重用父類的欄位和方法。除此之外,你還可以在當前類中添加新的欄位和方法。在Java中,類的繼承可以分為三種:單繼承,多繼承和分層繼承。但需要注意的是,這裡提到的多繼承是相對於被繼承類而言的,Java中不允許一個類繼承多個類。
  • 開課吧:學習編程,該學什麼語言?Python如何?
    編程編程如果是興趣方面的可以選擇比較簡單的入門語言入手,然後再慢慢切入到新的程式語言,目前相對來說比較好入門的程式語言是學習編程如果是帶著興趣去學基本上也就成功了一半,有了興趣能克服掉中間遇到問題直接放棄的衝動,有了興趣就會想盡一切辦法把自己武裝起來。編程裡面表燒腦不是寫代碼或者調試代碼的過程,而是算法的理解和程序的設計過程,這兩個方面能讓大腦覺得特別的充實。