當前位置:首頁 > 嵌入式 > 嵌入式軟件
[導讀] 本文詳細描述了一種利用 ptrace 系統(tǒng)調用,實現(xiàn)嵌入式系統(tǒng)內部進程通信的監(jiān)視方法,并提供了相應的實現(xiàn)方案。概述復雜的嵌入式系統(tǒng)中,常常同時運行著相當多的進程。這些進

 本文詳細描述了一種利用 ptrace 系統(tǒng)調用,實現(xiàn)嵌入式系統(tǒng)內部進程通信的監(jiān)視方法,并提供了相應的實現(xiàn)方案。

概述

復雜的嵌入式系統(tǒng)中,常常同時運行著相當多的進程。這些進程之間頻繁的進行著大量的通信動作。進程的運行狀態(tài)與這些不斷發(fā)生的通信有著直接和緊密的聯(lián)系。通過對進程間通信的監(jiān)視,開發(fā)人員可以掌控系統(tǒng)內部運轉的狀態(tài)。發(fā)現(xiàn)錯誤時,利用獲取到的進程間通信的信息,調試工程師更容易發(fā)現(xiàn)問題之所在。

但是,嵌入式系統(tǒng)與開發(fā)人員的接口往往較為單一。開發(fā)人員廣泛使用通常是基于串口或是網(wǎng)絡接口的終端( console )方式。在這個模式下,開發(fā)人員難以細致準確的觀察進程間的通信。而且對于計算能力薄弱的嵌入式系統(tǒng)來說,在終端上打印出通信報文既會影響系統(tǒng)內部的運行,同時,也會使屏幕上充斥的過多的無用信息,使開發(fā)人員的分析工作無從下手。

為了解決這個問題,在嵌入式 Linux 的平臺上,我們開發(fā)了一整套用于監(jiān)視嵌入式系統(tǒng)內進程間通信的軟件,用于調試我們開發(fā)的嵌入式產(chǎn)品。本文詳細介紹了監(jiān)視嵌入式系統(tǒng)內進程間通信的技術原理和實現(xiàn)監(jiān)視軟件的推薦方案。

監(jiān)視方法的基本原理

Linux 中的 ptrace 系統(tǒng)調用是監(jiān)視進程間通信的關鍵。 ptrace 為我們提供了一種觀察和控制其它進程的方法。利用 ptrace ,我們可以截獲正在運行的進程的所有的系統(tǒng)調用。所謂截獲是指,監(jiān)視程序可以在這些系統(tǒng)調用發(fā)生和退出時,獲得系統(tǒng)調用的參數(shù),甚至修改參數(shù)。這些系統(tǒng)調用包括: read , write , sendto, recv 等等。在 Linux 中,用戶可以通過“ man syscalls ”來查看當前版本的 Linux 所支持的系統(tǒng)調用。

在我們的 Linux 嵌入式產(chǎn)品中, AF_UNIX 域的 socket 被廣泛使用。它被用來完成進程間通信的工作。 AF_UNIX 域的 socket 的編程模型與通常的 socket 編程模型完全相同。我們的使用方法是:接收進程創(chuàng)建一個 AF_UNIX 域的 socket ,設定其模式為數(shù)據(jù)報( SOCK_DGRAM )。在這之后,為其綁定一個含路徑的文件名,例如: /var/tmp/receive.unix 。這個文件名被內核用于標識socket。發(fā)送進程創(chuàng)建一個相同模式的 AF_UNIX 域的 socket 。然后,調用 sendto 向接收進程發(fā)送消息。用來標識接收進程 socket 的就是前面提到的文件名,也就是 /var/tmp/receive.unix 。而接收進程使用 recvfrom 系統(tǒng)調用,就可以收到發(fā)送進程發(fā)出的消息。

因此,通過 ptrace ,一旦我們接管了被監(jiān)視進程的 sendto 和 recvfrom 系統(tǒng)調用,將使我們能夠截獲到使用這兩個系統(tǒng)調用進行通信的數(shù)據(jù)。

ptrace 系統(tǒng)調用的定義如下:

       #include <sys/ptrace.h> 
       long int ptrace(enum __ptrace_request request, pid_t pid, \
                       void * addr, void * data);

它共有四個參數(shù)。 request 的值決定 ptrace 執(zhí)行什么樣的任務。 pid 指明被追蹤的進程的 id 。 request 參數(shù)決定了是否需要一個有效的 addr 參數(shù),還是僅用 NULL 即可。如果有必要使用有效的 addr 參數(shù),它的含義是被追蹤的進程的進程空間的偏移量。 data 類似于 addr 參數(shù),有時也可以使用 NULL 來代替。如果它被使用,它的含義是指向一些數(shù)據(jù),這些數(shù)據(jù)希望被放置到被監(jiān)視的進程的用戶空間中。

一個完整的示例代碼將向我們展示監(jiān)視進程間通信的技術細節(jié)和關鍵點。代碼按前后順序分段說明。

               #include <stdio.h>
               #include <stdlib.h>[!--empirenews.page--]
               #include <sys/ptrace.h>
               #include <sys/wait.h>
               #include <linux/user.h>
               #include <sys/socket.h>
               #include <sys/un.h>
               #include <linux/net.h>

為了在程序中使用 ptrace 系統(tǒng)調用,我們需要增加 ptrace.h 頭文件。為了能夠獲得截獲的系統(tǒng)調用的函數(shù)入?yún)?,我們需要使?struct user_regs_struct 結構。它在 user.h 中被定義。由于在程序中使用了信號,因此,我們也需要 wait.h 。我們要監(jiān)視通信動作, socket.h 和 un.h 則是必不可少的。

下面是程序的入口主函數(shù):

        int main (int argc, char *argv[])
        {
            int status;
            int syscall_entry = 0;
            int traced_process;
            struct user_regs_struct u_in;

status 用于記錄被監(jiān)視進程的狀態(tài)變化; syscall_entry 記錄被監(jiān)視進程當前是進入系統(tǒng)調用,還是從系統(tǒng)調用中返回; u_in 用來獲得截獲的系統(tǒng)調用的參數(shù); traced_process 則是被監(jiān)視進程的 PID 值。

             traced_process = atoi(argv[1]); /* 從命令行得到監(jiān)視進程的PID */
             ptrace(PTRACE_ATTACH, traced_process, NULL, NULL);[!--empirenews.page--]
             wait(&status);    /* 等待被監(jiān)視進程狀態(tài)變化 */
             ptrace(PTRACE_SYSCALL, traced_process, NULL, NULL);

參數(shù)為 PTRACE_ATTACH 的 ptrace 對被監(jiān)視進程在內核中的進程結構進行修改。使被監(jiān)視進程成為當前程序的子進程。一旦被監(jiān)視進程的狀態(tài)發(fā)生變化, wait() 將返回。程序再次調用 ptrace 。這次的參數(shù)為 PTRACE_SYSCALL 。被監(jiān)視進程的進程結構再次被修改,其 trace 標志被激活。內核將在被監(jiān)視進程的每一次系統(tǒng)調用時,觸發(fā)當前程序的運行。

             While (1) {
                 /* 等待被監(jiān)視程序調用系統(tǒng)調用或是發(fā)生其它狀態(tài)變化 */
                 wait(&status); 
                 
                 /* 如果被監(jiān)視進程退出,函數(shù)返回真。程序退出 */
                 if ( WIFEXITED(status) ) 
                     break;
                 
                 ptrace(PTRACE_GETREGS, traced_process, 0, &u_in);
                 if (u_in.orig_eax == 102 && u_in.ebx == SYS_SENDTO) { 
                     if (syscall_entry == 0) {  /* syscall entry */
                         insyscall = 1;
                         printf("call sendto()\n");
                     }[!--empirenews.page--]
                     else {  /* Syscall exit */
                         Syscall_entry = 0;
                     }
                 }
                 ptrace(PTRACE_SYSCALL, traced_process, NULL, NULL);
              } /* while */
 
                           return 0;
                      }  /* main */

被監(jiān)視進程的 trace 標志被激活后,它的每一次系統(tǒng)調用都會被內核檢查。我們程序也隨之被內核用信號通知。使用參數(shù) PTRACE_GETREGS 的 ptrace() 將獲得截獲的系統(tǒng)調用的參數(shù)。最重要的參數(shù)是系統(tǒng)調用號。它保存在了 u_in.orig_eax 中。通過系統(tǒng)調用號,我們可以確定發(fā)生的是那一個系統(tǒng)調用。系統(tǒng)調用號可以在 Linux 的源代碼中查找。它的定義在 linux-source-2.6.xx/arch/x86/kernel/syscall_table_32.S 中。它的部分代碼如下所示:

            .long sys_fstatfs       /* 100 */
            .long sys_ioperm
            .long sys_socketcall
            .long sys_syslog

在這里,我們最關心的是 sendto 系統(tǒng)調用。在 Linux 的內核中, sendto 的真實入口是 socketcall 系統(tǒng)調用。它是 bind , sendto 等socket相關系統(tǒng)調用的入口。在這個系統(tǒng)調用中,通過一個 call number來區(qū)分出 bind , sendto 等不同的子系統(tǒng)調用。在我們的程序中,這個 call number 保存在 u_in.ebx 中。 從上面的 syscall_table_32.S 示例代碼就可以看出, socketcall 的系統(tǒng)調用號是102(從100向下數(shù)兩行)。而 call number 則在 net.h 有定義,我們關心的 sendto 的 call number 被定義為 SYS_SENDTO ,其絕對值為11。有了這兩個重要的數(shù)據(jù),我們的程序據(jù)此判斷當前發(fā)生的系統(tǒng)調用是否為 sendto 。這一點表現(xiàn)為代碼:

             if (u_in.orig_eax == 102 && u_in.ebx == SYS_SENDTO) [!--empirenews.page--]

被監(jiān)視進程進入系統(tǒng)調用和退出系統(tǒng)調用時,都會觸發(fā) wait() 返回,使我們的程序有機會運行。因此,我們需要使用 syscall_entry 來記錄當前時刻是被監(jiān)視進程進入系統(tǒng)調用,還是退出系統(tǒng)調用。這是一個開關量,非常容易理解。 最后,每次處理完,都需要再次調用參數(shù)為 PTRACE_SYSCALL 的 ptrace ,準備監(jiān)視下一次的系統(tǒng)調用。

上面的程序雖然很簡單,但已經(jīng)可以完整的表現(xiàn)出利用 ptrace 截獲被監(jiān)視進程的 sendto 系統(tǒng)調用的過程。值得補充一點的是,利用 ptrace 也可以獲得 sendto 向外發(fā)送的數(shù)據(jù)。

sendto 系統(tǒng)調用的定義是:

        #include <sys/types.h>
        #include <sys/socket.h>
        size_t sendto(int s, const void *msg, size_t len, int flags, \
                      const struct sockaddr *to, socket len_t tolen);

sendto 包含了六個參數(shù),特別是 msg 參數(shù)指出了發(fā)送的數(shù)據(jù)內容。參數(shù) to 指出了發(fā)送的目標。利用 PTRACE_PEEKDATA 參數(shù)的 ptrace ,監(jiān)視程序將可以獲得 sendto 的全部的六個參數(shù)。這樣監(jiān)視程序就完全獲得了被監(jiān)視進程要向外發(fā)送的數(shù)據(jù)和發(fā)送目標。具體的實現(xiàn)細節(jié)在此不再展開論述。請參考 man ptrace說明手冊。

監(jiān)視系統(tǒng)的體系和應用

利用上面討論的技術,我們開發(fā)了可以運行在 mips 目標板上的監(jiān)視程序,名為 ipcmsg 。它是一個命令行程序。在我們的應用環(huán)境中,它的使用方法是:

       root@host:~$ ipcmsg -p pid -l xxx.xxx.xxx.xxx -b 6000

pid 是被監(jiān)視進程的 pid ,可以通過 ps 命令獲得。 -l 參數(shù)后面指定 PC 主機的 IP 地址。 -b 參數(shù)指明了接收的端口號。

最初進行監(jiān)視時, ipcmsg 是沒有 IP 地址和端口號參數(shù)的。所有信息是輸出到串口控制臺中。這既影響了運行的效率(大量的在串口上的輸出會影響目標板的運行速度),也不利于信息的處理。由于我們的目標板具備以太網(wǎng)接口,我們很容易的想到將 ipcmsg 截獲的數(shù)據(jù)包轉發(fā)到 PC 主機上。使用 PC 主機更便于對進程間通信的數(shù)據(jù)包進行分析。在 PC 主機上,我們使用 wireshark 這個非常流行的開源的網(wǎng)絡報文分析軟件接收來自目標板的信息。

在實際的使用過程中,我們使用以太網(wǎng)線將目標板與 PC 主機相連。然后,在目標板上啟動 ipcmsg ,并為其指定監(jiān)視進程的 pid 。 ipcmsg運行后,我們在PC主機上啟動 wireshark 接收來自 ipcmsg 的數(shù)據(jù)包。這些數(shù)據(jù)包中包含了 mips 目標板上進程間通信的信息。利用我們?yōu)?ipcmsg 專門開發(fā)的 wireshark 插件,在 wireshark 上,我們可以詳細的分解 ipcmsg 轉發(fā)來的數(shù)據(jù)包,非常直觀的分析進程間通信的過程和可能存在的問題。

從圖中可以看到,我們從 ipcmsg 獲得了進程間通信的方式,參數(shù)( path 是 AF_UNIX域 socket 地址參數(shù)),方向和內容,以及進程名稱。這些信息幫助我們對嵌入式系統(tǒng)的運行狀態(tài)進行分析。而這一切非常直觀和便于操作。

本站聲明: 本文章由作者或相關機構授權發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內容真實性等。需要轉載請聯(lián)系該專欄作者,如若文章內容侵犯您的權益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或將催生出更大的獨角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉型技術解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關鍵字: 汽車 人工智能 智能驅動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務中斷的風險,如企業(yè)系統(tǒng)復雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務連續(xù)性,提升韌性,成...

關鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質量流程IT總裁陶景文發(fā)表了演講。

關鍵字: 華為 12nm EDA 半導體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權最終是由生態(tài)的繁榮決定的。

關鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務引領增長 以科技創(chuàng)新為引領,提升企業(yè)核心競爭力 堅持高質量發(fā)展策略,塑強核心競爭優(yōu)勢...

關鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術學會聯(lián)合牽頭組建的NVI技術創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術創(chuàng)新聯(lián)...

關鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關鍵字: BSP 信息技術
關閉
關閉