strcat segmentation fault

前端 未结 7 1873
后悔当初
后悔当初 2021-01-24 01:50

The second call to strcat here is generating a segmentation fault, why?

#include 
#include
#include 

        
7条回答
  •  梦谈多话
    2021-01-24 02:04

    I tried your code, and also see the segfault on the second strcat(). I found that command[250] is allocated immediately after whitespaceseparator[2] on the stack on my system:

    (gdb) p &whitespaceseparator 
    $1 = (char (*)[2]) 0xbf90acd4
    (gdb) p &command
    $2 = (char (*)[250]) 0xbf90acd6
    

    e.g. (here command begins "foo..."), things are layed out like this:

     whitespaceseparator
      |
      |      command
      |       |
      v       v
    +---+---+---+---+---+---+---+---+
    |' '| 0 |'f'|'o'|'o'|'.'|'.'|'.'| ...
    +---+---+---+---+---+---+---+---+
    

    I can't guarantee that the same happens on your system (layout of locals on the stack may vary even between different versions of the same compiler), but it seems likely. On mine, here is exactly what happens:

    As others have said, strcat() appends the second string to the first (and the result will be equal to the first argument). So, the first strcat() overflows whitespaceseparator[] (and returns whitespaceseparator as whitespace_and_pid):

    +---+---+---+---+---+---+---+---+
    |' '|'1'|'2'|'3'|'4'| 0 |'.'|'.'| ...
    +---+---+---+---+---+---+---+---+
    

    The second strcat() tries to append whitespace_and_pid (== whitespaceseparator) to the string at command. The first character of the copy will overwrite the terminating 0 of the string at command:

      |    ===copy===>    |
      v                   v
    +---+---+---+---+---+---+---+---+
    |' '|'1'|'2'|'3'|'4'|' '|'.'|'.'| ...
    +---+---+---+---+---+---+---+---+
    

    The copy continues...

          |    ===copy===>    |
          v                   v
    +---+---+---+---+---+---+---+---+
    |' '|'1'|'2'|'3'|'4'|' '|'1'|'.'| ...
    +---+---+---+---+---+---+---+---+
    
              |    ===copy===>    |
              v                   v
    +---+---+---+---+---+---+---+---+
    |' '|'1'|'2'|'3'|'4'|' '|'1'|'2'| ...
    +---+---+---+---+---+---+---+---+
    

    and will carry on copying " 1234 1234 1234"... until it falls off the end of the process address space, at which point you get a segfault.

提交回复
热议问题