0

I'm a newbie. I need to print the details of all process on the system. I have redirected the output of "ps -aux" to a text file and opened it in-order to display. Though I get the required details displayed correctly, I get stack smashing error and then segmentation fault. I could understand the segmentation fault is from one of the fgets/sscanf functions. May I know where might have I went wrong?

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 ++;
    }
}

Sample output is :

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: root@pts/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: root@notty
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 root@192.168.70.54
PID: 30597 size: 0.0 State: Ss CpuTime: 0:00 Cmd bash
PID: 30632 size: 0.0 State: S+ CpuTime: 0:00 Cmd ssh root@192.168.70.54
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
Dipto
  • 2,720
  • 2
  • 22
  • 42
Christy George
  • 309
  • 1
  • 5
  • 14
  • 1
    The initial `fgets()` makes no sense, are you skipping a header or something? Also, show more declarations. Perhaps `CurrProcessNum` is going out of range of `ProcVar`? – unwind Feb 24 '14 at 13:56
  • stack smashing means that the contents of stack frame of caller was somehow changed by callee. that's a security prevention against buffer overflows – mangusta Feb 24 '14 at 13:56
  • 2
    You're probably exceeding the array-size of `ProcVar`, to which you are continually incrementing the index into. – noelicus Feb 24 '14 at 13:57
  • `sscanf` might be exceeded argument for format specifier also what is size of array `ProcVar[?]`? might be index cause out of bound – Jayesh Bhoi Feb 24 '14 at 14:00
  • The best tool to investigate this is `valgrind`. – ams Feb 24 '14 at 14:11
  • What are the types of the various fields of `ProcVar[]`? Methinks you are reading *strings* into *integers*, with predictable results. Compile with *all* relevant compiler warnings enabled, and a modest optimization level (many warnings rely on information the copmpiler collects only when optimizing). – vonbrand Feb 24 '14 at 15:00
  • @unwind yes. the first fgets is to eat up the header..I tried printing the value of CurrProcessNum .But it is in the range of ProcVar. – Christy George Feb 25 '14 at 10:37
  • @mangusta Is there any way to deal with it? Can I avoid any changes? I only intend to save the values to contents, passed to the function. – Christy George Feb 25 '14 at 10:39
  • @noelicus I think I checked if its exceeding the array limit and it is verified. – Christy George Feb 25 '14 at 10:40
  • @vonbrand The structure contains the following fields 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]; }; – Christy George Feb 25 '14 at 10:43
  • @ChristyGeorge please add the structure to the question as an edit. – noelicus Feb 25 '14 at 11:51

2 Answers2

0

@vonbrand Please see the fields of the structure

   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];
 };
Christy George
  • 309
  • 1
  • 5
  • 14
0

From the code you've shown (which is still not enough for us to go on btw!) you're overwriting the stack with either (or perhaps both) of:

  1. You exceed the ProcVar array size as you don't check for array bounds
    (i.e. that CurrProcessNum < elements in the array)
  2. One of the strings you read into your array exceeds the length of CHAR_BUF_SIZE. To get around this you could utilise a safe version of sscanf. Microsoft have a safe sscanf called sscanf_s where you pass the buffer sizes in after the buffer argument. Or you could try and ditch sscanf altogether. Or use bigger buffers then copy those into your array using a safe string copy (e.g. strncpy).
noelicus
  • 14,468
  • 3
  • 92
  • 111