2014-02-24 31 views
0

我是一個新手。我需要打印系統上所有進程的詳細信息。我已將"ps -aux"的輸出重定向到一個文本文件並將其打開以便顯示。雖然我得到正確顯示所需的細節,但我得到堆棧粉碎錯誤,然後分段錯誤。我可以理解分段錯誤來自fgets/sscanf函數之一。我可以知道我哪裏可能會出錯嗎?堆棧粉碎檢測後分段錯誤

if (NULL != (FileDesc = fopen(FileName , "r"))) 
{ 
    if(! fgets(buf, sizeof(buf), FileDesc)) 
      { 
       Status = -1; 
      } 

    while(NULL != fgets(buf, sizeof(buf), FileDesc)) 
    { 
     sscanf(buf, "%*s %d %*s %s %*d %*d %*s %s %*s %s %[^\n] ", 
        &(ProcVar[CurrProcessNum].Pid), 
        &(ProcVar[CurrProcessNum].Size), 
        (ProcVar[CurrProcessNum].State), 
        (ProcVar[CurrProcessNum].CpuTime), 
        (ProcVar[CurrProcessNum].Cmd)); 
     printf (" PID: %d size: %s State: %s CpuTime: %s Cmd %s", 
           (ProcVar[CurrProcessNum].Pid), 
           (ProcVar[CurrProcessNum].Size), 
           (ProcVar[CurrProcessNum].State), 
           (ProcVar[CurrProcessNum].CpuTime), 
           (ProcVar[CurrProcessNum].Cmd)); 
     CurrProcessNum ++; 
    } 
} 

示例輸出:

PID: 21342 size: 0.0 State: S CpuTime: 0:00 Cmd [kjournald] 
PID: 23384 size: 2.6 State: Sl CpuTime: 39:59 Cmd /opt/Adobe/Reader9/Reader/intellinux/bin/acroread /root/Documents/Comcast_RDK2.0-B13.4_Broadcom_release_notes_20140123.pdf 
PID: 23495 size: 0.9 State: Ssl CpuTime: 9:01 Cmd gnome-terminal 
PID: 23498 size: 0.0 State: S CpuTime: 0:00 Cmd gnome-pty-helper 
PID: 23499 size: 0.0 State: Ss CpuTime: 0:00 Cmd bash 
PID: 26733 size: 0.1 State: Ss CpuTime: 0:18 Cmd sshd: [email protected]/3 
PID: 26843 size: 0.2 State: Ss CpuTime: 0:01 Cmd -bash 
PID: 26943 size: 0.1 State: Ss CpuTime: 0:06 Cmd sshd: [email protected] 
PID: 27052 size: 0.0 State: Ss CpuTime: 0:00 Cmd /usr/lib/openssh/sftp-server 
PID: 29510 size: 0.0 State: S CpuTime: 0:00 Cmd su root 
PID: 29517 size: 0.1 State: S+ CpuTime: 0:04 Cmd bash 
PID: 29951 size: 0.1 State: S+ CpuTime: 1:06 Cmd minicom 
PID: 30056 size: 0.0 State: Ss+ CpuTime: 0:00 Cmd bash 
PID: 30293 size: 0.0 State: Ss CpuTime: 0:00 Cmd bash 
PID: 30329 size: 0.0 State: S+ CpuTime: 0:01 Cmd ssh [email protected] 
PID: 30597 size: 0.0 State: Ss CpuTime: 0:00 Cmd bash 
PID: 30632 size: 0.0 State: S+ CpuTime: 0:00 Cmd ssh [email protected] 
PID: 31508 size: 0.0 State: Ss+ CpuTime: 0:00 Cmd bash 
PID: 31522 size: 0.1 State: Ss+ CpuTime: 0:00 Cmd bash 
*** stack smashing detected ***: bin/TR69_DM terminated 
Segmentation fault 
+1

最初的'fgets()'沒有任何意義,你是在跳過一個頭文件還是其他東西?此外,顯示更多的聲明。也許'CurrProcessNum'超出'ProcVar'的範圍? – unwind

+0

堆棧粉碎意味着調用者堆棧幀的內容被被調用者以某種方式改變。這是針對緩衝區溢出的安全預防 – mangusta

+2

您可能超過了'ProcVar'的數組大小,您不斷將索引增加到該數組大小。 – noelicus

回答

0

@vonbrand請參閱你所示的結構

struct ProcessInfo { 
char ProcName[CHAR_BUF_SIZE]; 
char Cmd[CHAR_BUF_SIZE]; 
char CpuTime[CHAR_BUF_SIZE]; 
int32_t Pid; 
int32_t Priority; 
char Size[CHAR_BUF_SIZE]; 
char State[CHAR_BUF_SIZE]; 
}; 
+0

這應該是對問題的編輯 - 這不是答案! – noelicus

0

從代碼的領域(這仍然是不夠的,我們繼續順便說一句!)你用(或可能兩者)覆蓋堆棧:

  1. 由於您不檢查數組 範圍
    CurrProcessNum < elements in the array
  2. 之一你讀入數組的字符串長度超過 CHAR_BUF_SIZE的長度。爲了解決這個問題,你可以使用sscanf的安全版本 。 Microsoft有一個safe sscanf called sscanf_s,其中 您在緩衝區參數後傳遞緩衝區大小。或者你可以嘗試和完全溝通sscanf。或者使用更大的緩衝區,然後使用安全字符串副本(例如strncpy)將 那些複製到您的陣列中。