精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Linux內核KGDB進階:源碼級調試實戰演練

系統 Linux
KGDB,即 Kernel GNU Debugger,是 Linux 內核官方支持的調試框架,就像是一位隱藏在幕后的超級特工,專門深入 Linux 內核的神秘世界,幫助開發者揪出那些隱藏極深的 Bug 。它采用 “雙機調試” 的獨特模型,這就好比一場精心策劃的秘密行動,需要兩個關鍵角色:目標機和開發機。

在 Linux 內核開發的廣袤領域中,調試工作堪稱一場充滿挑戰的冒險。用printk排障時對著日志猜邏輯,用ftrace跟蹤卻抓不到關鍵代碼執行路徑——這大概是每個Linux內核開發者都踩過的坑。內核空間的“黑盒”特性,讓多核競態、驅動死鎖這類問題成了調試路上的“硬骨頭”。而KGDB的出現,終于讓我們能像調試應用程序一樣,深入內核源碼逐行跟蹤、斷點調試。

不同于入門級的環境搭建,本文聚焦KGDB進階實戰:從串口調試到網絡調試的切換技巧,多核環境下斷點綁定核心的關鍵操作,再到驅動模塊動態加載后的符號匹配難題,全是一線開發中高頻遇到的場景。我們會以真實的網卡驅動異常案例為線索,演示如何用KGDB定位中斷處理函數的邏輯漏洞,如何通過觀察寄存器狀態還原問題現場。無論你是剛接觸內核調試的新手,還是被復雜問題困住的資深開發者,這份實戰指南都能幫你打通KGDB使用的“任督二脈”,讓內核調試不再靠“猜”。

一、什么是KGDB?

1.1KGDB概述

KGDB,即 Kernel GNU Debugger,是 Linux 內核官方支持的調試框架,就像是一位隱藏在幕后的超級特工,專門深入 Linux 內核的神秘世界,幫助開發者揪出那些隱藏極深的 Bug 。它采用 “雙機調試” 的獨特模型,這就好比一場精心策劃的秘密行動,需要兩個關鍵角色:目標機和開發機。目標機是運行著需要被調試內核的 “任務現場”,可以是一臺物理機器,也可以是虛擬機,它通過特定的 I/O 端口,通常是串口 ttyS0 或者以太網,悄無聲息地輸出調試信息,同時時刻準備接收來自開發機的調試指令 。

開發機則是運行著 GDB(或 LLDB)的 “指揮中心”,通過相同的 I/O 端口與目標機緊密相連,向目標機發送各種調試命令,比如讀取內存數據、設置斷點等,然后等待目標機反饋的 “情報” 。

  • 開發機(Development Machine):運行GDB調試器,負責發送調試命令并接收目標機反饋,需部署內核源碼及編譯產物。
  • 目標機(Target Machine):運行待調試內核,通過串口或以太網與開發機通信,內核需集成KGDB調試Stub(實現調試協議解析與環境交互的內核模塊)。

目前KGDB已支持x86_64、i386、32-bit PPC等主流架構,適用于內核崩潰排查、驅動開發調試、內存越界分析等核心場景。在這個過程中,目標機內核中的 KGDB stub(存根)起著至關重要的作用,它就像是目標機和開發機之間的 “秘密聯絡官”。KGDB stub 與開發機的 GDB 之間通過一種基于包的特定協議進行通信,這個協議就像是他們之間的 “秘密語言”,運行在串行線或以太網之上 。當目標機內核啟動后,KGDB stub 就開始靜靜地等待開發機的連接,如同潛伏的特工等待總部的指令。

一旦目標機遇到斷點、異常,或者通過魔術鍵(Magic SysRq)手動觸發調試,內核的執行會立即完全停止,就像時間突然靜止一樣。此時,控制權迅速移交給 KGDB stub,stub 通過通信端口向開發機的 GDB 發送一個 “異常” 信號,仿佛在向總部報告:“發現情況,請求指示!” 開發機的 GDB 接收到信號后,立即進入交互模式,開發者就可以像指揮官一樣,開始下達各種調試命令了。在 GDB 中輸入 c(continue)命令后,調試指令就會被發送回目標機,內核從停止的地方繼續執行,就像按下了播放鍵,時間又開始流動。

1.2KGDB 相比其他工具的優勢

與傳統的 printk 調試方式相比,KGDB 簡直就是降維打擊。printk 就像是在黑暗中摸索,只能通過打印一些簡單的日志信息來猜測程序的運行狀態,一旦遇到復雜的問題,這些零散的信息就如同大海撈針,很難從中找到關鍵線索 。而 KGDB 則擁有 “上帝視角”,它允許開發者設置斷點,就像在程序的關鍵位置埋下了 “監控攝像頭”,可以讓程序在特定的位置暫停執行,方便開發者仔細檢查此時的變量值、寄存器狀態等信息 。例如,當調試一個復雜的內核模塊時,如果使用 printk,可能需要在代碼中到處添加打印語句,不僅繁瑣,而且可能會因為打印過多的信息而導致系統性能下降。而使用 KGDB,只需要在關鍵函數或代碼行設置斷點,就可以輕松地查看程序在斷點處的詳細狀態,大大提高了調試效率。

再看看 ftrace,它雖然能夠跟蹤函數的調用關系,幫助開發者了解程序的執行流程,但在調試復雜問題時,還是顯得力不從心 。ftrace 無法像 KGDB 那樣,精確地控制程序的執行,進行單步調試,也不能直接查看寄存器和內存的詳細信息 。比如,當遇到一個涉及到硬件寄存器操作的內核問題時,ftrace 就很難提供有效的幫助,而 KGDB 卻可以直接查看寄存器的值,分析問題的根源。

在面對多核競態問題時,KGDB 的優勢更是凸顯。它可以在多線程同時訪問共享資源的關鍵代碼處設置斷點,然后通過單步執行,仔細觀察每個線程在不同時刻對共享資源的操作,從而找出競態條件產生的原因 。而其他工具,如 printk 和 ftrace,很難在這種復雜的多線程環境中,準確地定位問題。例如,在一個多核處理器的文件系統驅動中,當多個線程同時讀寫文件緩存時,可能會出現數據不一致的問題。使用 KGDB,開發者可以在緩存操作的關鍵函數處設置斷點,逐步跟蹤每個線程的執行過程,找到導致數據不一致的具體操作步驟。

二、KGDB 調試內核核心原理

2.1基本原理剖析

KGDB 的工作基于 GDB 遠程調試協議,其運行機制依賴于兩臺機器的協同工作,即調試主機(Host)和目標機(Target) 。在調試過程中,調試主機上運行著 GDB 調試器,它就像是一位經驗豐富的指揮官,負責向目標機發送各種調試指令,掌控整個調試流程的節奏。而目標機則運行著被調試的 Linux 內核以及 KGDB,它如同一位正在執行任務的士兵,按照 GDB 的指令行事,并將自身的狀態信息及時反饋給調試主機。

當在目標機的內核代碼中設置斷點后,一旦程序執行到斷點位置,目標機內核就會立刻暫停當前的執行流程。此時,它會將當前的執行環境,包括寄存器值、內存狀態等關鍵信息,按照 GDB 遠程調試協議的規定,通過串口或網絡發送給調試主機上的 GDB 。GDB 收到這些信息后,就如同收到了前線傳來的戰報,會根據開發者輸入的調試命令,如繼續執行、單步執行、查看變量等,進行相應的分析和處理,并向目標機內核發送對應的指令。

目標機內核在接收到這些指令后,會如同接到新的作戰任務一樣,迅速做出響應,執行相應的操作,并將操作結果再次返回給 GDB 。通過這樣緊密的交互過程,開發者就能夠像操控自己手中的玩具一樣,對 Linux 內核進行高效的調試,精準地定位和解決問題。

2.2安裝KGDB

(1)安裝環境要求

設備)類型

核心配置

必備軟件

開發機

x86_64架構,2核4G以上配置

GDB(7.12+)、內核源碼、補丁工具(patch)、SCP工具

目標機

支持的架構,與開發機通信鏈路正常

待調試Linux內核、串口驅動(或網卡驅動)

(2)通信鏈路準備

KGDB支持串口和以太網兩種通信方式,需根據場景選擇并完成物理連接或網絡配置:

  • 串口連接(推薦嵌入式場景):使用RS-232交叉串口線,連接兩臺機器的串口接口,線序為"開發機TXD-目標機RXD、開發機RXD-目標機TXD、雙方GND直連"。
  • 以太網連接(推薦云服務器/VPS場景):確保開發機與目標機處于同一局域網或網絡可達,開放調試端口(如1234)防火墻權限。

核心文件準備:

  • 1. 內核源碼與KGDB補丁:需確保補丁版本與內核版本匹配,補丁命名規則為"linux-A-kgdb-B"(A為內核版本,B為KGDB版本),例如linux-2.6.7對應kgdb-2.2補丁。
  • 2. 下載地址參考:內核源碼從http://kernel.org獲取,KGDB補丁可從內核官方補丁庫或嵌入式社區獲取。

(3)安裝與配置步驟

通信鏈路測試(串口場景必做),完成串口物理連接后,通過以下命令驗證通信可用性(以/dev/ttyS0為例,波特率115200):

  • 開發機配置串口參數:stty ispeed 115200 ospeed 115200 -F /dev/ttyS0
  • 目標機配置串口參數:stty ispeed 115200 ospeed 115200 -F /dev/ttyS0
  • 開發機發送測試數據:echo "kgdb test" > /dev/ttyS0
  • 目標機接收數據:cat /dev/ttyS0,若輸出"kgdb test"則連接正常。

②內核補丁應用(開發機操作)

解壓內核源碼與KGDB補丁:

tar -jxvf linux-2.6.7.tar.bz2
tar -jxvf linux-2.6.7-kgdb-2.2.tar.bz2
cd linux-2.6.7

按補丁包內series文件指定順序應用補丁(i386架構示例),避免順序錯誤導致沖突:

patch -p1 < ../linux-2.6.7-kgdb-2.2/core-lite.patch
patch -p1 < ../linux-2.6.7-kgdb-2.2/i386-lite.patch
patch -p1 < ../linux-2.6.7-kgdb-2.2/8250.patch  # 串口驅動補丁
patch -p1 < ../linux-2.6.7-kgdb-2.2/eth.patch   # 以太網調試需加此補丁
patch -p1 < ../linux-2.6.7-kgdb-2.2/core.patch
patch -p1 < ../linux-2.6.7-kgdb-2.2/i386.patch

檢查補丁應用結果:若未生成*.rej文件,說明補丁應用成功。

③內核配置(開發機操作),通過內核配置菜單啟用KGDB相關功能,確保調試符號完整保留:

  • 啟動配置界面:make menuconfig
  • 進入"Kernel hacking"菜單,勾選以下選項: (*) KGDB: kernel debugging with remote gdb(啟用KGDB核心功能)
  • Method for KGDB communication → 選擇通信方式(串口選"KGDB: On generic serial port (8250)",以太網選對應網卡選項)
  • (*) KGDB: Thread analysis(線程分析支持)
  • (*) KGDB: Console messages through gdb(調試過程中控制臺消息轉發)
  • (*) Compile the kernel with debug info(保留調試符號,CONFIG_DEBUG_INFO=y)
  • (*) KGDB_KDB(可選,啟用KDB本地調試輔助)
  • 保存配置并退出(默認保存至.config文件)。

④內核編譯與部署

  • 調整編譯優化級別:打開內核目錄下的Makefile,將-O2優化級別改為-O(避免編譯器重排代碼導致調試錯位),不可完全移除-O選項(會導致編譯失敗)。
  • 編譯內核與模塊:
make -j$(nproc)  # 多線程編譯,$(nproc)為CPU核心數
make modules -j$(nproc)
make modules_install  # 安裝內核模塊
make install  # 安裝內核
  • 生成initrd鏡像(若驅動未編譯進內核):mkinitrd /boot/initrd-2.6.7-kgdb 2.6.7
  • 部署至目標機:通過SCP將內核文件、System.map和initrd鏡像拷貝到目標機/boot目錄:
scp arch/x86_64/boot/bzImage root@目標機IP:/boot/vmlinuz-2.6.7-kgdb
scp System.map root@目標機IP:/boot/System.map-2.6.7-kgdb
scp /boot/initrd-2.6.7-kgdb root@目標機IP:/boot/initrd-2.6.7-kgdb

⑤目標機啟動配置,通過修改GRUB配置,讓目標機使用帶KGDB的內核啟動并加載調試參數:

  • 編輯GRUB配置文件:vim /etc/default/grub
  • 修改GRUB_CMDLINE_LINUX參數,根據通信方式添加對應配置: 串口調試:GRUB_CMDLINE_LINUX="kgdbwait kgdboc=ttyS0,115200" 參數說明:kgdbwait(內核啟動時等待GDB連接)、kgdboc(指定通信設備與波特率)
  • 以太網調試(VPS場景):GRUB_CMDLINE_LINUX="kgdbwait kgdboc=eth0,192.168.1.100:1234" 若用串口轉TCP:在開發機執行socat -d -d TCP-LISTEN:1234,reuseaddr,fork FILE:/dev/ttyS0,raw,echo=0實現端口轉發
  • 更新GRUB配置:update-grub(Debian/Ubuntu)或grub2-mkconfig -o /boot/grub2/grub.cfg(CentOS/RHEL)
  • 重啟目標機:reboot,啟動時選擇帶"kgdb"標識的內核,系統會掛起并等待GDB連接(屏幕顯示"Waiting for connection from remote gdb")。

2.3關鍵功能部件解析

GDB stub:GDB stub,又被親切地稱為調試插樁,它可是 KGDB 調試器的核心部件,就像是人體的心臟一樣重要 。它是一段巧妙嵌入 Linux 內核中的代碼,雖然身材短小,但卻肩負著重大的使命。它主要負責處理主機上 GDB 發來的各種請求,這些請求就像是來自上級的各種任務,GDB stub 需要準確無誤地理解并執行。比如,當 GDB 要求查看某個變量的值時,GDB stub 就得迅速在目標機的內核中找到該變量,并將其值反饋給 GDB。同時,在內核處于被調試狀態時,GDB stub 還承擔著控制目標機上處理器的重任,它就像是一位嚴謹的交通警察,指揮著處理器的每一個動作,確保調試過程的順利進行。

陷阱處理:陷阱處理在 KGDB 調試中扮演著至關重要的角色,它就像是一位時刻保持警惕的衛士。當開發者在代碼中設置斷點時,KGDB 會迅速提供一個異常處理函數,這個函數就像是一個神奇的魔法棒,它會將斷點位置的指令替換成一條異常指令。當程序執行到該斷點時,異常就會如同警報一樣被觸發,內核就會立即將 CPU 的控制權交給 KGDB 調試器。此時,程序就會進入 KGDB 提供的異常處理函數中,在這個函數里,開發者就像是進入了一個神秘的實驗室,可以對內核代碼的各種情況進行深入的分析和研究,比如查看變量的值、檢查寄存器的狀態等,從而找到問題的根源。

串口通信:串口通信是 KGDB 實現調試主機與目標機之間信息交互的重要橋梁,它基于 gdb 串行協議進行工作。gdb 串行協議是一種精心設計的基于消息的 ASCII 碼協議,它就像是一種特殊的語言,包含了各種調試命令。調試主機和目標機就像是兩個用這種特殊語言交流的伙伴,通過串口發送和接收這些包含調試命令和執行結果的消息。例如,當調試主機上的 GDB 發送一個設置斷點的命令時,這個命令就會通過串口,按照 gdb 串行協議的格式,被準確地傳送到目標機的 KGDB stub。KGDB stub 在接收到這個命令后,會根據命令的要求進行相應的操作,并將操作結果再通過串口,按照協議格式返回給 GDB 。串口通信的穩定性和準確性直接影響著調試的效果,就像道路的暢通與否會影響交通的效率一樣。

三、準備工作:用KGDB調試內核

3.1環境搭建

為了開啟這場 KGDB 的實戰之旅,我們首先需要搭建一個合適的環境。這里我們以 QEMU 虛擬機作為目標機,它就像是一個虛擬的實驗室,讓我們可以在其中自由地調試內核,而不用擔心對真實的物理設備造成影響 。

配置串口是第一步,這就好比在兩座城市之間搭建一條通信線路。在啟動 QEMU 虛擬機時,我們通過添加 “-serial tcp:[127.0.0.1:1234](127.0.0.1:1234),server,nowait” 參數,創建了一個 TCP 連接的虛擬串口 。這個串口就像是一座橋梁,將目標機(QEMU 虛擬機)和開發機連接起來,使得它們之間能夠進行調試信息的傳輸。

在虛擬機內部,我們還需要啟用串口設備。這一步就像是在城市內部鋪設道路,讓信息能夠順利地在虛擬機內部傳遞。我們可以通過修改虛擬機的引導配置文件,比如在 GRUB 配置文件 “/boot/grub/grub.cfg” 中,添加以下內容:

serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal_input serial
terminal_output serial

這樣,虛擬機就啟用了串口設備,并將終端輸入 / 輸出都重定向到了串口上,為后續的調試通信做好了準備。

接下來是準備根文件系統,它就像是虛擬機的 “倉庫”,存儲著運行所需的各種文件和程序 。我們可以從網上下載一個已經預先構建好的根文件系統鏡像,比如 “rootfs_deb.img.7z”,當然,你也可以自己動手構建一個最小化的根文件系統,使用 busybox 來實現基本的命令功能 。如果選擇下載,下載完成后,我們需要將其解壓到合適的目錄,比如 “/home/user/rootfs”。這個過程就像是把貨物搬進倉庫,為虛擬機的運行提供必要的資源。

3.2內核配置與編譯

進入內核源碼目錄,就像是踏入了一個神秘的代碼王國。在這里,我們使用 “make menuconfig” 命令,開啟內核配置的大門 。這是一個基于文本的圖形界面,就像是一個商品琳瑯滿目的超市,我們可以在其中自由地選擇需要的功能。在這個界面中,我們要開啟幾個關鍵的選項,就像是在超市中挑選必備的商品。首先是 CONFIG_KGDB,它是 KGDB 的核心功能開關,啟用它就像是啟動了一臺強大的機器CONFIG_KGDB_SERIAL_CONSOLE,這個選項用于通過串口進行 KGDB 通信,就像是連接了一條穩定的通信線路;還有 CONFIG_DEBUG_INFO,它至關重要,會包含 DWARF 調試信息,使 GDB 能夠識別符號和源代碼,就像是給代碼王國中的每個物品都貼上了標簽,方便我們查找和識別 。此外,CONFIG_DEBUG_INFO_DWARF4(推薦使用較新的 DWARF 格式)和 CONFIG_FRAME_POINTER(生成更可靠的調用棧回溯)等選項也可以根據需要開啟。

完成配置后,我們就可以保存配置并開始編譯內核了。編譯內核的過程就像是一場緊張的生產活動,需要消耗一定的時間和系統資源 。我們執行 “make -j$$(nproc)”命令,其中“-$$(nproc)” 表示使用多個線程并行編譯,這樣可以大大加快編譯速度,就像是工廠里增加了生產線,提高了生產效率。編譯完成后,不要忘記安裝新內核,執行 “make modules_install” 和 “make install” 命令,將新編譯的內核模塊和內核安裝到系統中,就像是把生產好的產品擺放到合適的位置,讓系統能夠使用它們。

3.3設置啟動參數

設置啟動參數是使用 KGDB 調試內核的重要環節,它就像是給一艘船設定航行的方向,只有方向設定正確了,船才能順利到達目的地。在設置啟動參數之前,我們需要為 KGDB 內核創建一個新的啟動項,這個新的啟動項就像是為我們的調試之旅開辟了一條新的航道。

我們可以通過修改系統的啟動配置文件來創建新啟動項。在大多數 Linux 系統中,這個文件通常是/etc/grub.conf或/boot/grub/grub.cfg。在這個文件中,我們要添加一些關鍵參數。首先是kgdboc參數,它用于指定串口和波特率,比如kgdboc=ttyS0,115200,這就像是給調試主機和目標機之間的通信通道設定了一個標準,讓它們能夠以相同的頻率進行交流。如果我們想要調試內核的啟動階段,還需要添加kgdbwait參數,它會使目標機在啟動時等待調試連接,就像一個耐心的伙伴,在原地等待我們的到來 。

在修改啟動配置文件時,一定要注意備份原有的啟動項和相關文件,這就像是在進行一次重要的旅行之前,備份好所有重要的文件和資料。因為一旦修改出現問題,我們還可以恢復到原來的狀態,避免因為配置錯誤而導致系統無法啟動的情況發生。修改完成后,我們需要保存文件,并重啟目標機,使新的啟動參數生效,這樣我們就完成了啟動參數的設置,可以進入下一步的調試工作了。

3.4建立調試連接

在完成前面的準備工作后,接下來就進入了建立調試連接的關鍵步驟,這一步就像是在調試主機和目標機之間搭建一座橋梁,讓兩者能夠進行順暢的通信。

我們首先要在開發機上啟動 GDB。GDB 作為調試的核心工具,就像是一位經驗豐富的領航員,將帶領我們深入探索目標機內核的奧秘。在啟動 GDB 時,我們可以通過在終端中輸入gdb命令,然后加載目標二進制文件,比如gdb vmlinux,這里的vmlinux就是我們之前從目標機拷貝到開發機上的內核二進制文件,它包含了內核的所有代碼和數據,是我們調試的主要對象 。

啟動 GDB 后,我們需要設置遠程調試相關參數。如果我們使用串口連接進行調試,就需要設置串口連接參數。在 GDB 界面中,我們可以使用set remotebaud命令來設置波特率,使其與之前在目標機啟動參數中設置的波特率一致,比如set remotebaud 115200,確保通信的速率匹配。然后使用target remote命令來指定連接的串口設備,例如target remote /dev/ttyS0,這里的/dev/ttyS0就是我們之前配置好的串口設備,通過這兩個命令,我們就像在調試主機和目標機之間的串口通信線路上安裝了正確的信號發射器和接收器,讓它們能夠準確無誤地傳輸調試信息。

如果我們使用網絡連接進行調試,設置過程會稍有不同。我們需要使用target remote命令指定目標機的 IP 地址和端口號,比如target remote 192.168.1.10:1234,其中192.168.1.10是目標機的 IP 地址,1234是預先設置好的端口號,這就像是在調試主機和目標機之間的網絡通道上設置了正確的門牌號,讓調試信息能夠準確地找到目標機。

設置好遠程調試參數后,GDB 就會嘗試與目標機建立連接。如果一切順利,我們會看到 GDB 界面顯示已經成功連接到目標機,并且可能會顯示當前斷點停在kgdb_breakpoint函數處,這就表明我們成功地在調試主機和目標機之間搭建起了調試橋梁,接下來就可以進行各種調試操作了 。但如果連接過程中出現問題,比如提示無法連接或者通信錯誤,我們就需要仔細檢查之前的配置步驟,包括串口或網絡連接是否正確、啟動參數是否設置無誤等,確保每一個環節都沒有問題,直到成功建立調試連接。

四、KGDB 實戰演練

4.1連接與初始化

現在,所有的準備工作已經就緒,就像是一場大戰前的一切戰略部署都已完成,我們終于要開啟這場激動人心的 KGDB 實戰之旅了 。

①首先,在開發機上,我們要啟動 GDB,這就像是啟動了一臺強大的武器。打開終端,進入之前準備好的內核源碼目錄,執行 “gdb vmlinux” 命令,GDB 就被成功啟動,并且加載了內核的調試符號 ,就像給武器裝上了精準的瞄準鏡,讓我們能夠更準確地定位問題。你需要有與目標機完全一致的、包含調試信息的vmlinux文件(編譯內核時在源碼根目錄生成的那個,不是/boot下的壓縮鏡像)。

cd /path/to/linux-kernel-source
gdb ./vmlinux

②接下來,要建立與目標機的連接,這一步至關重要,就像是搭建起一座通往問題核心的橋梁。由于我們之前在 QEMU 虛擬機中配置了串口通信,這里使用 “target remote /dev/pts/XX” 命令,其中 “/dev/pts/XX” 是 QEMU 啟動時分配的串口設備,這個命令就像是在向目標機發出連接請求 。當連接成功時,你會看到 GDB 的界面發生了變化,這表明我們已經成功地與目標機建立了聯系,就像兩個秘密特工成功接頭一樣,為后續的調試工作奠定了基礎。

對于串口:

(gdb) set serial baud 115200
(gdb) target remote /dev/ttyS0  # 請替換為開發機上的實際串口設備

對于QEMU創建的TCP端口:

(gdb) target remote 127.0.0.1:1234

連接成功后,我們就可以開始設置斷點了,斷點就像是我們在程序執行路徑上設置的 “關卡”,可以讓程序在特定的位置暫停,方便我們進行調試 。假設我們懷疑內核中處理網絡包接收的函數 “netif_receive_skb” 存在問題,就可以在 GDB 中執行 “b netif_receive_skb” 命令,這樣就在 “netif_receive_skb” 函數的入口處設置了一個斷點 。當程序執行到這個函數時,就會停在斷點處,等待我們進一步的調試指令,就像車輛行駛到關卡時,會被攔下接受檢查一樣。

常用GDB命令

  • break function_name 或 b function_name:在函數處設置斷點(例如:b sys_open)。
  • break filename.c:linenumber:在指定文件的指定行設置斷點。
  • c (continue):繼續執行。
  • next 或 n:單步跳過。
  • step 或 s:單步進入。
  • print variable_name 或 p variable_name:打印變量值。
  • bt (backtrace):打印調用棧回溯,這是分析Panic/Oops的利器。
  • info registers:顯示所有寄存器內容。
  • lx-symbols (需要手動加載):極其重要! 如果你需要調試內核模塊,在連接上目標機后,在GDB中執行:
(gdb) lx-symbols /path/to/target-machine-kernel-modules/

這個命令(內核提供的GDB腳本)會自動加載所有已加載模塊的符號表。

在運行時手動觸發調試會話

如果啟動時沒有加kgdbwait,你可以在目標機系統運行過程中,通過魔術SysRq鍵強制它進入調試狀態。

  • 確保已啟用SysRq:echo 1 > /proc/sys/kernel/sysrq
  • 在目標機鍵盤上按下:Alt + SysRq + g(在某些系統上,可能是 Alt + PrintScreen + g,或者通過 echo g > /proc/sysrq-trigger)

按下后,目標機內核會凍結,并通過調試端口等待GDB連接。此時你再從開發機用GDB連上去即可。

4.2調試過程演示

以調試網絡驅動為例,當我們設置好斷點后,就可以在目標機上觸發網絡包的輸入了。在另一個終端中,對 QEMU 虛擬機執行 “ping [10.0.2.15](10.0.2.15)” 命令,向虛擬機發送網絡數據包 ,這就像是向目標機的網絡驅動 “發起挑戰”,看看它能否正確處理這些數據包。

當網絡包到達目標機時,內核開始處理網絡包的接收流程。由于我們之前在 “netif_receive_skb” 函數設置了斷點,程序執行到這里時,會立即停住 ,就像時間突然靜止了一樣。此時,GDB 的界面會顯示當前停住的位置以及相關的函數調用信息 ,就像給我們展示了一張程序執行的 “快照”。

我們可以使用 “info args” 命令查看當前函數的參數,這就像是查看一個神秘包裹里的物品清單 。比如,在 “netif_receive_skb” 函數斷點處執行 “info args”,可以看到傳遞給這個函數的網絡數據包的相關參數,如數據包的指針、長度等信息,通過這些信息,我們可以初步判斷數據包是否正確地傳遞到了這個函數中 。“p” 命令也是非常有用的,它可以打印變量的值,就像一個神奇的放大鏡,讓我們能夠看清程序內部的細節 。例如,執行 “p skb”,這里 “skb” 是網絡數據包的結構體變量,通過這個命令,我們可以查看數據包的具體內容,包括數據的長度、包頭的信息等,從而進一步分析問題 。如果發現數據包的某個字段值異常,就可以順著這個線索繼續深入調試。

單步跟蹤也是調試過程中常用的技巧,通過 “n”(next)命令可以單步執行下一條語句,“s”(step)命令則可以進入函數內部執行 。當我們懷疑某個函數內部的代碼存在問題時,就可以使用 “s” 命令進入函數,一步一步地查看代碼的執行過程,觀察變量的變化情況,就像偵探在案發現場仔細地尋找線索一樣 。比如,在 “netif_receive_skb” 函數中,我們發現某個變量的值在某一步之后出現了異常,就可以使用單步跟蹤,逐步分析是哪一條語句導致了這個異常的發生。

4.3問題解決與驗證

經過一番細致的調試和分析,我們終于定位到了問題所在。假設我們發現是網絡驅動在處理接收緩沖區時,存在內存越界的問題,導致數據包丟失 。那么,我們就需要提出解決方案,這就像是醫生為病人開出治療方案一樣。針對這個內存越界的問題,我們可以修改代碼邏輯,在訪問接收緩沖區之前,增加對緩沖區邊界的檢查 。打開內核源碼中網絡驅動的相關文件,找到處理接收緩沖區的代碼部分,添加如下檢查代碼:

if (skb->len + offset > buffer_size) {
    // 處理內存越界的情況,比如返回錯誤或者調整緩沖區
    return -EINVAL;
}

修改完代碼后,我們需要重新編譯內核,這就像是對修改后的程序進行 “組裝”,讓它能夠正常運行 。在目標機的內核源碼目錄中,執行 “make -j$(nproc)” 命令進行編譯,編譯完成后,執行 “make modules_install” 和 “make install” 命令,將新編譯的內核模塊和內核安裝到系統中 。

重新啟動目標機,再次進行網絡包的測試,執行 “ping [10.0.2.15](10.0.2.15)” 命令 。如果之前的丟包問題得到了解決,ping 命令能夠正常返回響應,就說明我們的修改是有效的,問題得到了成功解決 。為了進一步驗證問題是否徹底解決,我們還可以進行壓力測試,比如使用 “iperf” 工具,向目標機發送大量的網絡數據包,觀察在高并發情況下,網絡驅動是否還會出現丟包的問題 。如果在壓力測試中,網絡驅動能夠穩定地工作,沒有出現丟包現象,那么就可以確定我們的解決方案是正確的,這場 KGDB 的實戰調試也取得了圓滿的成功 。

五、使用 KGDB 的小竅門

5.1常用命令與技巧

在使用 KGDB 進行內核調試時,熟練掌握一些常用的 GDB 命令和技巧,能夠讓你的調試工作事半功倍 。首先是斷點設置命令 “b”(break),它是我們調試的 “偵察兵”,可以在函數或特定代碼行設置斷點 。比如 “b sys_read”,這會在系統調用 “sys_read” 的入口處設置斷點,當內核執行到這個函數時,就會停下來,方便我們進行檢查 。如果要在某個源文件的具體行號設置斷點,比如 “b fs/read_write.c:50”,就會在 “read_write.c” 文件的第 50 行設置斷點 。

“c”(continue)命令就像是調試的 “加速器”,它會讓內核從當前斷點繼續執行,直到遇到下一個斷點或程序結束 。當我們查看完當前斷點處的信息,想要繼續觀察程序的執行時,就可以使用這個命令 。

“n”(next)和 “s”(step)命令則是我們深入程序內部的 “放大鏡” 。“n” 命令會單步執行下一條語句,但不會進入函數內部,適合快速跳過一些我們不關心的函數調用 。而 “s” 命令會進入當前函數的下一個語句,直到遇到新的一行或函數結束,當我們想要深入研究某個函數內部的執行邏輯時,“s” 命令就派上用場了 。例如,在調試一個網絡驅動時,我們可以使用 “s” 命令進入網絡包處理函數,一步一步地查看數據的處理過程 。“p”(print)命令是查看變量值的利器,它就像是一個神奇的 “透視鏡”,能夠讓我們看清程序內部變量的狀態 。執行 “p my_variable”,就可以打印出 “my_variable” 這個變量的值 。如果變量是一個復雜的結構體,我們還可以通過 “p my_struct.member” 的方式,查看結構體中某個成員的值 。比如,在調試一個文件系統驅動時,我們可以使用 “p inode->i_size”,查看文件節點的大小 。

“bt”(backtrace)命令是分析程序執行流程的 “時間軸”,它會打印出當前的調用棧回溯信息,幫助我們了解函數的調用關系 。當內核出現崩潰或異常時,通過 “bt” 命令,我們可以看到函數的調用順序,從而找到問題的根源 。比如,在分析一個內核 Oops 錯誤時,“bt” 命令可以顯示出錯誤發生時的函數調用棧,讓我們能夠快速定位到出錯的函數 。

除了這些基本命令,設置觀察點也是一個非常有用的技巧 。觀察點就像是一個 “監控攝像頭”,可以監視某個變量的變化,當變量的值發生改變時,程序就會暫停執行 。使用 “watch variable_name” 命令,就可以設置一個觀察點,當 “variable_name” 這個變量的值發生變化時,GDB 會自動暫停,讓我們可以檢查變量變化的原因 。比如,在調試一個多線程程序時,我們可以設置觀察點來監視共享變量的變化,從而找出競態條件的問題 。

使用 GDB 腳本也是提高調試效率的好方法 。GDB 腳本就像是一個自動化的 “助手”,可以預先設置一系列的調試命令,然后一次性執行 。我們可以將一些常用的斷點設置、變量查看等命令編寫成腳本,每次調試時直接加載腳本,就可以快速進入調試狀態 。例如,我們可以編寫一個腳本,在啟動 GDB 時自動連接到目標機,并設置好常用的斷點 。創建一個名為 “my_script.gdb” 的文件,在其中寫入以下內容:

target remote /dev/pts/XX
b sys_open
b sys_close

5.2常見問題與解決方法

在使用 KGDB 的過程中,難免會遇到一些問題 。首先是斷點設置失敗的問題,這可能是由于多種原因導致的 。如果目標代碼位于優化后的函數或被內聯(inlined)執行,就會導致源碼行與實際指令地址不匹配,從而使斷點無法命中 。此時,我們可以在源碼中添加 “attribute((noinline))” 來強制禁用內聯,或者在編譯內核時使用 “-fno-inline” 選項 。例如,在某個函數定義前添加 “attribute((noinline)) static void my_function () {... }”,這樣在編譯時這個函數就不會被內聯 。

如果內核配置未啟用調試信息(如未定義 CONFIG_DEBUG_INFO),GDB 就無法正確解析符號和行號,也會導致斷點設置失敗 。我們需要重新配置內核,確保 CONFIG_DEBUG_INFO 選項被啟用 。在 “make menuconfig” 的配置界面中,找到 “Kernel hacking -> Compile the kernel with debug info”,將其設置為 “y” 。

斷點設置在尚未加載的模塊代碼中,也會導致斷點無法生效 。對于動態加載的模塊,我們需要先加載模塊,然后再設置斷點 。可以使用 “add-symbol-file” 命令,告知 GDB 模塊的符號位置 。例如,執行 “(gdb) add-symbol-file /path/to/module.ko 0xc0008000”,其中 “/path/to/module.ko” 是模塊文件的路徑,“0xc0008000” 是模塊的加載地址 。

串口沖突也是一個常見的問題 。如果串口被其他程序占用,比如 getty 或 minicom,就會導致 KGDB 無法正常通信 。我們需要確保串口僅被 KGDB 獨占 。可以通過查看系統日志,檢查串口設備是否被其他程序打開 。在 Linux 系統中,可以使用 “lsof /dev/ttyS0” 命令(假設串口設備是 ttyS0),查看哪些程序在使用這個串口 。如果發現有其他程序占用,可以先關閉這些程序,或者修改 KGDB 的配置,使用其他未被占用的串口 。

符號文件不匹配也可能引發問題 。調試時使用的 vmlinux 文件必須與目標內核完全一致,包括編譯時間戳和配置 。如果 vmlinux 文件不匹配,GDB 可能無法正確解析符號,導致調試錯誤 。每次編譯內核后,我們都要確保保留對應的 vmlinux 文件,并通過 “file vmlinux” 命令驗證其 Build ID 。如果發現 vmlinux 文件不匹配,需要重新拷貝正確的 vmlinux 文件到開發機上 。

責任編輯:武曉燕 來源: 深度Linux
相關推薦

2021-10-17 19:52:40

Python:源碼編譯器

2025-10-27 01:55:00

2014-08-28 15:08:35

Linux內核

2010-01-22 11:01:04

linux內核模塊

2017-09-25 08:04:31

Linux調試器源碼級斷點

2022-05-23 09:22:20

Go語言調試器Delve

2011-08-22 13:56:09

Linux虛擬

2017-08-28 15:29:19

Linux調試器源碼級逐步執行

2017-01-12 19:15:03

Linux內核調試自構proc

2021-07-11 06:45:18

Linux內核靜態

2022-02-08 15:15:26

OpenHarmonlinux鴻蒙

2017-03-17 15:05:05

Linux內核源碼do_fork

2009-09-18 14:31:33

CLR觸發器

2009-08-09 20:39:11

Linux內核虛擬環境虛擬主機

2023-04-10 09:44:22

內核鼠標調試鴻蒙

2016-08-23 09:17:08

LinuxD狀態TASK_RUNNIN

2025-03-05 00:49:00

Win32源碼malloc

2025-05-27 08:20:00

Linux內核參數調優系統

2021-12-29 11:51:15

Linux 內核源碼Linux 系統

2023-04-28 08:42:08

Linux內核SPI驅動
點贊
收藏

51CTO技術棧公眾號

亚洲天堂免费| 91av亚洲| 成人av网站免费观看| 欧美在线视频一区| 国精产品视频一二二区| 秋霞一区二区| 在线观看视频一区| 国产青草视频在线观看| 国产免费a∨片在线观看不卡| 久久国产精品免费| 97精品久久久中文字幕免费| 午夜国产福利视频| 久久97精品| 欧美日本一区二区在线观看| 黄色免费观看视频网站| av网址在线| 国产亚洲va综合人人澡精品| 国产精品二区在线观看| 波多野结衣黄色| 亚洲国产高清视频| 自拍偷拍亚洲一区| 欧美双性人妖o0| 国产精品久久久久久久久久辛辛 | 一区二区不卡在线视频 午夜欧美不卡'| 国产女人18毛片水18精| 久久av在线| 久久久久一本一区二区青青蜜月| 顶级黑人搡bbw搡bbbb搡| 一本色道久久综合狠狠躁的番外| 91精品视频网| 国产原创精品在线| 亚洲欧洲自拍| 福利微拍一区二区| 黄色污污在线观看| 日本免费在线观看| 欧美高清在线一区二区| 免费试看一区| 欧美熟妇交换久久久久久分类 | 国产精品一区二区三区四区五区| 一级日韩一级欧美| 久久福利毛片| 日本国产一区二区三区| 日韩三级av在线| 欧美特黄a级高清免费大片a级| 在线观看精品自拍私拍| 88久久精品无码一区二区毛片| 97品白浆高清久久久久久| 91精品国产综合久久久久| 欧美大尺度做爰床戏| 免费观看成人性生生活片| 疯狂做受xxxx欧美肥白少妇| 蜜桃传媒一区二区三区| √8天堂资源地址中文在线| 一区二区久久久| av片在线免费| xxxx另类黑人| 婷婷综合另类小说色区| 一女被多男玩喷潮视频| xx欧美视频| 色狠狠色狠狠综合| www欧美激情| 日韩深夜福利网站| 欧美一区二区三区视频免费| 91性高潮久久久久久久| 天堂精品在线视频| 精品国产自在久精品国产| 又黄又色的网站| 女同一区二区三区| 亚洲人成电影网站| 亚洲自拍偷拍图| 久久国产中文字幕| 另类图片亚洲另类| 国产亚洲第一页| 99av国产精品欲麻豆| 日韩av不卡电影| 在线观看国产黄| 国产精品91一区二区| 国产精品乱码视频| 午夜福利视频一区二区| 久久久99精品免费观看不卡| 亚洲国产综合自拍| 色呦呦在线免费观看| 性感美女久久精品| 中文字幕第36页| 久久久91麻豆精品国产一区| 亚洲精品在线观| 无码人妻精品一区二区中文| 91亚洲人成网污www| 欧美国产视频日韩| 91视频在线视频| 国产精品亚洲午夜一区二区三区| 国产视色精品亚洲一区二区| 国产女人在线观看| 一个色在线综合| 青青在线视频免费| 免费高清在线观看电视| 欧美一级二级三级区| 国产精品久久久久9999吃药| 国产免费裸体视频| 成人自拍av| 精品精品欲导航| 日韩不卡av在线| 在线观看一区视频| 国产精品一区专区欧美日韩| 粉嫩av一区二区夜夜嗨| 91丨porny丨最新| 亚洲成人动漫在线| xx欧美视频| 精品1区2区在线观看| 国产又粗又猛又爽又黄的视频小说| 韩日精品在线| 国产欧美精品日韩精品| 午夜国产在线视频| 亚洲人成7777| 超碰在线97免费| 国产成人精品一区二区三区视频 | 97视频资源在线观看| 国产区在线视频| 欧美日韩人人澡狠狠躁视频| 91香蕉视频在线观看视频| 国产欧美一区二区精品久久久| 久久久女女女女999久久| 一二三区在线播放| 2020国产精品| 成年人看的毛片| 只有精品亚洲| 中文字幕综合一区| 国产免费av一区| 不卡视频在线观看| 91制片厂免费观看| 久久精品资源| 国产一区二区三区18| 免费在线不卡视频| 成a人片国产精品| 成人在线免费观看视频网站| 91精品亚洲一区在线观看| 尤物九九久久国产精品的分类| 日产精品久久久| caoporn国产一区二区| 成人短视频在线观看免费| 成人在线啊v| 久久艳片www.17c.com | 韩国三级在线一区| 亚洲欧洲精品一区二区三区波多野1战4 | 中文字幕不卡在线观看| 国产一区亚洲二区三区| 综合伊思人在钱三区| 全球成人中文在线| 玖玖综合伊人| 在线观看网站黄不卡| 亚洲一区二区三区日韩| 久久亚洲视频| 色之综合天天综合色天天棕色| 日韩欧美看国产| 中文字幕久久久av一区| 在线免费观看一级片| 国产精品久99| 一二三av在线| 欧美a级片一区| 国产精品theporn88| 老牛影视精品| 亚洲免费视频网站| 一区二区视频免费| 18成人在线视频| 女人扒开双腿让男人捅| 亚洲大片av| 欧美精品久久久| 亚洲成人一区在线观看| 深夜福利91大全| 99久久久久久久| 亚洲国产精品麻豆| 人妻少妇一区二区| 老司机免费视频一区二区三区| 自拍偷拍99| 动漫av一区| 国产精品成人播放| 免费av网站在线看| 亚洲成av人影院在线观看| 日本三级小视频| 国产精品无人区| 人妻巨大乳一二三区| 99精品视频免费观看| 日本精品二区| 国产区一区二| 97婷婷涩涩精品一区| av免费在线一区二区三区| 日韩一区二区三区视频在线观看 | 亚洲一区一卡| 神马影院午夜我不卡| 日韩精品一区二区三区免费视频| 456国产精品| 黄色成人影院| 日韩精品免费在线视频观看| 91丨porny丨在线中文 | 久久久久久久久久久久久久久久久久久久| 68精品国产免费久久久久久婷婷| 欧美三级黄网| 日韩电影网在线| 国产精品羞羞答答在线| 精品久久久久久久大神国产| 污污的视频在线免费观看| av在线播放成人| 欧洲美女亚洲激情| 首页国产欧美日韩丝袜| 国内自拍中文字幕| 欧美特黄一级大片| 国产亚洲欧美一区二区| 成人午夜sm精品久久久久久久| 欧美精品videosex牲欧美| 东凛在线观看| 亚洲精品电影网| 国产乱码精品一区二三区蜜臂| 欧美日韩性视频在线| 麻豆视频在线免费看| 欧美激情自拍偷拍| 私密视频在线观看| 国产精品一区二区久久精品爱涩| 国产亚洲天堂网| 在线观看视频免费一区二区三区| 波多野结衣激情| 久久99国内| 久久精品日产第一区二区三区乱码| 国产视频一区二| 国产日韩中文在线| 影视一区二区三区| 欧美孕妇毛茸茸xxxx| av伦理在线| 欧美国产乱视频| jizz性欧美10| 麻豆成人在线看| 麻豆传媒在线免费| 中日韩午夜理伦电影免费 | 国产一区二区三区中文字幕| 在线精品视频小说1| caoporn国产| 欧美日韩在线看| 青青草手机在线视频| 亚洲欧美精品午睡沙发| 国产尤物在线播放| 综合久久久久久| 黄色录像一级片| 中文字幕亚洲成人| 中文字幕在线观看2018| 亚洲欧美日本在线| 免看一级a毛片一片成人不卡| 亚洲女女做受ⅹxx高潮| 懂色av懂色av粉嫩av| 一区二区三区中文字幕| 久久国产精品波多野结衣| 亚洲精品国产一区二区精华液 | 国产精品magnet| 黄色成人在线免费观看| 激情综合视频| 秋霞无码一区二区| 校园春色综合网| 日本中文字幕片| 免费看日韩精品| 亚洲欧美aaa| 国产成人免费av在线| 自拍一级黄色片| 成人午夜激情影院| 亚洲永久无码7777kkk| 久久亚洲捆绑美女| 免费黄在线观看| 综合久久久久综合| 国产精品111| 日韩欧美在线字幕| 啪啪小视频网站| 制服.丝袜.亚洲.另类.中文| 国产欧美一级片| 亚洲大胆人体在线| 欧美xxx.com| 日韩在线观看免费网站 | 久久视频精品| www.激情网| 久久久久91| av在线网址导航| 国产a级毛片一区| 欧美特黄一区二区三区| 国产精品毛片久久久久久| 男女做暖暖视频| 欧美日韩免费网站| 97国产成人无码精品久久久| 精品国产伦一区二区三区观看方式| 天天影院图片亚洲| 日韩一区二区三区国产| 国产精品偷拍| 国产精品久久久久福利| 2021年精品国产福利在线| 玛丽玛丽电影原版免费观看1977 | 亚洲免费av高清| 黄网在线观看视频| 欧美高清视频一二三区| 日韩在线视频免费| 色偷偷偷亚洲综合网另类| av老司机在线观看| 成人a在线视频| 日韩精品丝袜美腿| 蜜臀av.com| 日韩高清国产一区在线| 在线观看网站黄| 国产欧美一区二区精品婷婷| 国产一级片网址| 欧美日韩免费在线视频| 亚洲aaa在线观看| 欧美成人免费va影院高清| 欧美福利在线播放| 国产欧美日韩一区二区三区| 午夜精品一区二区三区国产 | 亚洲无码精品一区二区三区| 日韩女优电影在线观看| seseavlu视频在线| 性欧美长视频免费观看不卡| 免费一级欧美在线大片 | 欧美日韩四区| 亚洲男人天堂色| 91网站最新网址| 久久久久成人精品无码| 欧美精三区欧美精三区| 极品美乳网红视频免费在线观看| 久久久久久999| 日韩一区二区三区高清在线观看| 日韩欧美一区二区在线观看 | 香蕉av一区二区| 亚洲综合日韩欧美| 国产视频一区不卡| 丰满人妻老熟妇伦人精品| 亚洲国产成人精品电影| 免费电影视频在线看 | 蜜桃成人av| 99视频在线免费播放| 成人晚上爱看视频| 久久伊人成人网| 日韩欧美成人激情| 污污的视频在线观看| 91在线播放国产| 91成人影院| 亚洲一区二区三区三州| 最新欧美精品一区二区三区| 亚洲无码精品在线播放| 日韩在线一区二区三区免费视频| 日本韩国欧美| 日韩av电影免费播放| 日日夜夜精品视频免费| 国产精品无码久久久久一区二区| 大桥未久av一区二区三区| 色欲av伊人久久大香线蕉影院| 久久免费观看视频| 精品综合久久88少妇激情| 青青青免费在线| 91麻豆精品在线观看| 超碰超碰超碰超碰| 亚洲人成欧美中文字幕| 婷婷激情一区| 中日韩在线视频| 国产乱码精品一区二区三区忘忧草| 51精品免费网站| 精品久久久久久久久久久久久久久 | 99久久精品国产一区二区成人| www.日韩av.com| 久久三级中文| 久操网在线观看| 26uuu成人网一区二区三区| 最新中文字幕在线观看视频| 中文字幕亚洲欧美| 精品三级国产| 免费看黄在线看| 久久久久久久久蜜桃| 一区二区三区在线免费观看视频| 久久亚洲私人国产精品va| 高清日韩欧美| 天天天干夜夜夜操| 亚洲乱码一区二区三区在线观看| 人妻偷人精品一区二区三区| 日av在线播放中文不卡| 999久久久精品国产| 性猛交╳xxx乱大交| 色综合天天综合狠狠| 欧美日韩在线看片| 国产日韩亚洲精品| 日本欧美一区二区| 九九九免费视频| 亚洲欧美日韩精品久久亚洲区| 四虎国产精品永久在线国在线| 日韩成人三级视频| 国产亚洲综合性久久久影院| 国产成人精品一区二区无码呦| 91精品国产沙发| 四季av在线一区二区三区| 中文视频在线观看| 欧美视频在线一区二区三区 | 久久精品国产一区二区三区日韩| 久久国产视频网| 日本网站免费观看| 色综合亚洲精品激情狠狠| 国产精东传媒成人av电影| 91蝌蚪视频在线观看| 亚洲综合免费观看高清完整版| 岛国在线大片| 国产视频精品网|