• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 使用GDB與QEMU調試內核時的問題分析

    發表于:2007-05-26來源:作者:點擊數: 標簽:
    使用QEMU+GDB能夠實現源代碼級的內核調試,但是,存在一個問 題──當內核允許中斷時,單步命令(n與s)會進入時鐘中斷。通過 瀏覽QEMU的源代碼,大體把原因找了出來。單步命令(n與s)在 gdb遠程調試通訊協議中是s(參看infogdb),qemu的gdbstub 在受到s命
    使用QEMU+GDB能夠實現源代碼級的內核調試,但是,存在一個問
    題──當內核允許中斷時,單步命令(n與s)會進入時鐘中斷。通過
    瀏覽QEMU的源代碼,大體把原因找了出來。 單步命令(n與s)在
    gdb遠程調試通訊協議中是s(參看info gdb),qemu的gdb stub
    在受到s命令后將虛擬CPU進入單步狀態,但是在接收到s命令前,
    qemu的虛擬CPU是停止的(在等待gdb的命令),注意,這個時
    候,虛擬時鐘計時并沒有停止,所以,很可能在qemu的虛擬CPU還
    沒開始的時候就需要觸發時鐘中斷了,但是虛擬CPU還在停止狀態,
    中斷無法觸發。接收到s命令后,虛擬CPU開始執行指令。這時,如
    果內核允許中斷,虛擬時鐘就將觸發中斷,所以s命令執行一條指令
    后停止在時鐘中斷處理程序的開始處,而不是希望的函數中下一條指
    令處。

      現在看一下問題的解決方法。在我看來,需要修改gdb遠程調試內核
    時單步命令的語義。有兩個方向。
    1.在gdb上修改。在處理用戶的n與s命令時不是發送協議中的s命令,
    而是分兩步。首先確定下一條指令的開始位置(或者下一行源程序對應
    的指令的開始位置)。對于有些RISC機器機器指令固定為某個長度,那
    么確定這個位置比較簡單,但是對于像x86這樣的變長指令的體系結構
    就需要稍微麻煩一點(需要確定當前指令的長度等)。然后假如第一步
    確定的地址是naddr?,F在像處理用戶的tbreak *naddr一樣處理就可
    以了,接著發送繼續運行命令c就可以了。
    2.在qemu的gdb stub上修改協議命令s的處理方法。接收到s命令后
    不是讓虛擬CPU進入單步執行狀態,而是確定在沒有中斷的情況下,下
    一條指令的位置(注意對于當前是跳轉指令的情況處理比較復雜),然
    后在這個位置設置臨時斷點,在虛擬CPU到達這個斷點進入gdb stub
     后立即將其取消。

    這兩種處理方法中,我認為1比較好,實現起來清晰明了,但是需要對
    gdb的代碼比較熟悉。2方法比較復雜,尤其是在當前指令是跳轉指令
    時,不太容易確定臨時斷點的位置。

    另外作為暫時的權宜之計,我們可以只使用tbreak +offset來代替n
    與s命令。

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>