<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 手機(jī)與無線通信 > 設(shè)計(jì)應(yīng)用 > 監(jiān)視嵌入式系統(tǒng)內(nèi)進(jìn)程間通信的技術(shù)原理

          監(jiān)視嵌入式系統(tǒng)內(nèi)進(jìn)程間通信的技術(shù)原理

          作者: 時(shí)間:2010-12-14 來源:網(wǎng)絡(luò) 收藏

          本文詳細(xì)描述了一種利用 ptrace 調(diào)用,實(shí)現(xiàn)內(nèi)部方法,并提供了相應(yīng)的實(shí)現(xiàn)方案。
          概述

          本文引用地址:http://www.ex-cimer.com/article/156878.htm

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

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

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

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

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

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

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

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

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

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

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

          #include stdio.h>
          #include stdlib.h>
          #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)調(diào)用,我們需要增加 ptrace.h 頭文件。為了能夠獲得截獲的系統(tǒng)調(diào)用的函數(shù)入?yún)?,我們需要使?struct user_regs_struct 結(jié)構(gòu)。它在 user.h 中被定義。由于在程序中使用了信號(hào),因此,我們也需要 wait.h 。我們要監(jiān)視通信動(dòng)作, 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)視進(jìn)程的狀態(tài)變化; syscall_entry 記錄被監(jiān)視進(jìn)程當(dāng)前是進(jìn)入系統(tǒng)調(diào)用,還是從系統(tǒng)調(diào)用中返回; u_in 用來獲得截獲的系統(tǒng)調(diào)用的參數(shù); traced_process 則是被監(jiān)視進(jìn)程的 PID 值。

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

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

          While (1) {
          /* 等待被監(jiān)視程序調(diào)用系統(tǒng)調(diào)用或是發(fā)生其它狀態(tài)變化 */
          wait(status);

          /* 如果被監(jiān)視進(jì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);
          }
          else { /* Syscall exit */
          Syscall_entry = 0;
          }
          }
          ptrace(PTRACE_SYSCALL, traced_process, NULL, NULL);
          } /* while */

          return 0;
          } /* main */
          linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)

          上一頁 1 2 3 下一頁

          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();