Getting Segmentation Fault, selectively, on memory overwrite.

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Vishal Grover

    Getting Segmentation Fault, selectively, on memory overwrite.

    Hello Everyone,

    I am seeing a certain behaviour which I find strange, and am curious to get an
    explanation to it. I have the following program.

    #include <iostream>
    #include <cstdlib>

    using namespace std;

    int main(int argc, char ** argv) {
    if(argc<2) {
    return -1;
    }

    int value = atoi(argv[1]);
    char * arr = new char[value];
    // No segmentation fault unless next is an array.
    char * next = new char[value];

    int i = 0;
    for(i=0; i<value; i++) {
    arr[i] = 'a';
    next[i] = 'a';
    }
    // NOTE: I am adding a char beyond the array boundary
    arr[i]='\0';
    next[i]='\0';
    // This causes a segmentation fault
    delete [] arr;
    }

    I compiled this with 3.2.2 on Red Hat Linux 9 on an Intel i686. When I run the
    program, it gives me a Segmentation fault only when the array size is an odd
    multiple of 4. My guess is it has something to do with word alignment. But, what
    exactly is happening here?

    Thanks for your help,
    Vishal Grover
    Developer
    Trilogy Software Inc.
  • Kevin Goodsell

    #2
    Re: Getting Segmentation Fault, selectively, on memory overwrite.

    Vishal Grover wrote:
    [color=blue]
    > Hello Everyone,
    >
    > I am seeing a certain behaviour which I find strange, and am curious to get an
    > explanation to it. I have the following program.
    >
    > #include <iostream>
    > #include <cstdlib>
    >
    > using namespace std;
    >
    > int main(int argc, char ** argv) {
    > if(argc<2) {
    > return -1;
    > }
    >
    > int value = atoi(argv[1]);
    > char * arr = new char[value];
    > // No segmentation fault unless next is an array.
    > char * next = new char[value];
    >
    > int i = 0;
    > for(i=0; i<value; i++) {
    > arr[i] = 'a';
    > next[i] = 'a';
    > }
    > // NOTE: I am adding a char beyond the array boundary[/color]

    If you know this, why are you surprised that the program doesn't behave
    well?
    [color=blue]
    > arr[i]='\0';
    > next[i]='\0';
    > // This causes a segmentation fault
    > delete [] arr;
    > }
    >
    > I compiled this with 3.2.2 on Red Hat Linux 9 on an Intel i686. When I run the
    > program, it gives me a Segmentation fault only when the array size is an odd
    > multiple of 4.[/color]

    That's perfectly acceptable behavior for a program with undefined behavior.
    [color=blue]
    > My guess is it has something to do with word alignment. But, what
    > exactly is happening here?[/color]

    Undefined behavior.
    [color=blue]
    >
    > Thanks for your help,
    > Vishal Grover
    > Developer
    > Trilogy Software Inc.[/color]

    I'm considering making a note of this company's name so I can be sure
    never to buy software from them... Can you explain *why* you are
    intentionally overflowing an array in your code, in order to restore
    some of my confidence in the software industry?

    -Kevin
    --
    My email address is valid, but changes periodically.
    To contact me please use the address from a recent posting.

    Comment

    • Josephine Schafer

      #3
      Re: Getting Segmentation Fault, selectively, on memory overwrite.


      "Vishal Grover" <vishal_grover@ rediffmail.com> wrote in message
      news:a60c0ad7.0 309092050.544f8 0ae@posting.goo gle.com...[color=blue]
      > Hello Everyone,
      >
      > I am seeing a certain behaviour which I find strange, and am curious to[/color]
      get an[color=blue]
      > explanation to it. I have the following program.
      >
      > #include <iostream>
      > #include <cstdlib>
      >
      > using namespace std;
      >
      > int main(int argc, char ** argv) {
      > if(argc<2) {
      > return -1;
      > }
      >
      > int value = atoi(argv[1]);
      > char * arr = new char[value];
      > // No segmentation fault unless next is an array.
      > char * next = new char[value];
      >
      > int i = 0;
      > for(i=0; i<value; i++) {
      > arr[i] = 'a';
      > next[i] = 'a';
      > }
      > // NOTE: I am adding a char beyond the array boundary[/color]

      But why? You haven't allocated enough space to write another extra
      character.
      Strings do end with a null character but then you need to allocate space for
      that null character
      also. I hope you know that.

      Taking that into consideration -
      char * arr = new char[value + 1];
      char * next = new char[value + 1];
      should be what would get you the desired result.

      HTH,
      J.Schafer





      Comment

      • Vishal Grover

        #4
        Re: Getting Segmentation Fault, selectively, on memory overwrite.

        Kevin Goodsell
        [color=blue][color=green]
        > > // NOTE: I am adding a char beyond the array boundary[/color]
        >
        > If you know this, why are you surprised that the program doesn't behave
        > well?[/color]

        Because, this is a test case which I had written to investigate a bug. I am
        not questioning the fact that the program doesn't behave well. My question
        is why isn't the behaviour not uniform for each input value.
        [color=blue][color=green]
        > > I compiled this with 3.2.2 on Red Hat Linux 9 on an Intel i686. When I run the
        > > program, it gives me a Segmentation fault only when the array size is an odd
        > > multiple of 4.[/color]
        >
        > That's perfectly acceptable behavior for a program with undefined behavior.[/color]

        Nowhere have I claimed that the behaviour is not acceptable. I am just looking
        for an explanation for the behaviour.
        [color=blue][color=green]
        > > My guess is it has something to do with word alignment. But, what
        > > exactly is happening here?[/color]
        >
        > Undefined behavior.[/color]

        No machine or compiler, at least the non-quantum ones, has a non-deterministic
        behaviour, given perfect knowledge about the system. In case you did not
        get the question, I was looking for an insight on how does a popular
        compiler like gcc handle undefined behaviour.
        [color=blue]
        >
        > I'm considering making a note of this company's name so I can be sure
        > never to buy software from them... Can you explain *why* you are
        > intentionally overflowing an array in your code, in order to restore
        > some of my confidence in the software industry?
        >[/color]

        Since when is it a bad practice, to write a test case to investigate a potential
        bug? You have no right to question the quality of software that
        my company makes, based on what I has been given in this mail. If you can't
        supply a decent answer, or even if this is not the right place to ask the
        question, you have absolutely no right to be rude and make such judgemental
        statements.
        [color=blue]
        > -Kevin[/color]

        Thank you very much Kevin, I will not be posting any further questions on this
        list

        Vishal

        Comment

        • Vishal Grover

          #5
          Re: Getting Segmentation Fault, selectively, on memory overwrite.

          Josephine,

          I am sorry, if I did not ask the question clearly enough.
          [color=blue][color=green]
          > > // NOTE: I am adding a char beyond the array boundary[/color]
          >
          > But why? You haven't allocated enough space to write another extra
          > character.
          > Strings do end with a null character but then you need to allocate space for
          > that null character
          > also. I hope you know that.[/color]

          Yes, I know that and I am overwriting the memory intentionally. I was curious
          to know, how would a typical compiler handle such a case. Yes, the behaviour
          is indeed undefined according to the language standards in such a case. However,
          given a combination of Operating System and Compiler, the behaviour of the
          program will have an explanation and I was interested in that explanation.
          Maybe, this group is the wrong place to ask this question.
          [color=blue]
          > Taking that into consideration -
          > char * arr = new char[value + 1];
          > char * next = new char[value + 1];
          > should be what would get you the desired result.
          > HTH,
          > J.Schafer[/color]

          Thank You,
          Vishal

          Comment

          • Kevin Goodsell

            #6
            Re: Getting Segmentation Fault, selectively, on memory overwrite.

            Vishal Grover wrote:[color=blue]
            > Kevin Goodsell
            >
            >[color=green][color=darkred]
            >>> // NOTE: I am adding a char beyond the array boundary[/color]
            >>
            >>If you know this, why are you surprised that the program doesn't behave
            >>well?[/color]
            >
            >
            > Because, this is a test case which I had written to investigate a bug. I am
            > not questioning the fact that the program doesn't behave well. My question
            > is why isn't the behaviour not uniform for each input value.[/color]

            There is no C++ language answer for that. You might be able to get an
            answer from the compiler vendor. All the C++ standard has to say about
            it is that it places no requirements on the program's behavior.
            [color=blue]
            >
            > Since when is it a bad practice, to write a test case to investigate a potential
            > bug? You have no right to question the quality of software that
            > my company makes, based on what I has been given in this mail. If you can't
            > supply a decent answer, or even if this is not the right place to ask the
            > question, you have absolutely no right to be rude and make such judgemental
            > statements.[/color]

            You posted blatantly broken code without an explanation or any
            indication that you understood that it was broken. What conclusion
            should I draw from that? I only asked for an explanation, to hopefully
            show my conclusion was wrong.
            [color=blue]
            >
            > Thank you very much Kevin, I will not be posting any further questions on this
            > list
            >[/color]

            It's a group, not a list. Honestly, I care very little whether you
            participate or not. But this is a rather trivial thing to resort to
            self-banishment over.

            -Kevin
            --
            My email address is valid, but changes periodically.
            To contact me please use the address from a recent posting.

            Comment

            • Alf P. Steinbach

              #7
              Re: Getting Segmentation Fault, selectively, on memory overwrite.

              On 9 Sep 2003 21:50:13 -0700, vishal_grover@r ediffmail.com (Vishal Grover) wrote:
              [color=blue]
              >I am seeing a certain behaviour which I find strange, and am curious to get an
              >explanation to it. I have the following program.
              >
              >#include <iostream>
              >#include <cstdlib>
              >
              >using namespace std;
              >
              >int main(int argc, char ** argv) {
              > if(argc<2) {
              > return -1;
              > }
              >
              > int value = atoi(argv[1]);
              > char * arr = new char[value];
              > // No segmentation fault unless next is an array.
              > char * next = new char[value];
              >
              > int i = 0;
              > for(i=0; i<value; i++) {
              > arr[i] = 'a';
              > next[i] = 'a';
              > }
              > // NOTE: I am adding a char beyond the array boundary
              > arr[i]='\0';
              > next[i]='\0';
              > // This causes a segmentation fault
              > delete [] arr;
              >}
              >
              >I compiled this with 3.2.2 on Red Hat Linux 9 on an Intel i686. When I run the
              >program, it gives me a Segmentation fault only when the array size is an odd
              >multiple of 4. My guess is it has something to do with word alignment. But, what
              >exactly is happening here?[/color]

              As others have answered, the only general answer is that you're invoking
              undefined behavior, where anything or nothing may happen.

              In practice it seems your compiled program is overwriting some allocation
              information.

              Such information is typically placed right before a dynamically allocated
              item. That seems to fit the alignment issue you have noted. It's no
              great mystery, but it has nothing to do with C++.

              On the topic of C++, in order of appearance in the above code:


              * Guideline: don't use atoi, since it has no error checking.
              Exception: where you want 0 as result in case of error (add comment).

              * Guideline: don't use raw pointers and arrays, use smart pointers and
              standard library containers.

              * Guideline: avoid using a loop control variable after the loop.

              * Guideline: always execute a corresponding 'delete' for each 'new'.

              * Guideline: when you rely on the return value 'main' to indicate
              failure, express success explicitly by returning EXIT_SUCCESS.


              Finally, Word of Advice: don't take technical comments personally and
              threaten to "leave this list", as you seem to have done; see e.g.
              <url:http://www.winternet.c om/~mikelr/flame52.html>.

              Comment

              • Noah Roberts

                #8
                Re: Getting Segmentation Fault, selectively, on memory overwrite.

                Vishal Grover wrote:[color=blue]
                > Josephine,
                >
                > I am sorry, if I did not ask the question clearly enough.
                >
                >[color=green][color=darkred]
                >>> // NOTE: I am adding a char beyond the array boundary[/color]
                >>
                >>But why? You haven't allocated enough space to write another extra
                >>character.
                >>Strings do end with a null character but then you need to allocate space for
                >>that null character
                >>also. I hope you know that.[/color]
                >
                >
                > Yes, I know that and I am overwriting the memory intentionally. I was curious
                > to know, how would a typical compiler handle such a case. Yes, the behaviour
                > is indeed undefined according to the language standards in such a case. However,
                > given a combination of Operating System and Compiler, the behaviour of the
                > program will have an explanation and I was interested in that explanation.
                > Maybe, this group is the wrong place to ask this question.[/color]

                You cannot know for sure what will happen when you write past a
                dynamically created storage area. You could be attempting to overwrite
                basically anything. Maybe the next byte is yours, maybe it isn't.
                There is not even a compiler specific answer.

                You can know what you will be overwriting if you go past a stack
                allocated memory segment. Usually this will be more stack variables and
                eventually the return value. This is how buffer overrun exploits occur.

                NR

                Comment

                • Josephine Schafer

                  #9
                  Re: Getting Segmentation Fault, selectively, on memory overwrite.


                  "Vishal Grover" <vishal_grover@ rediffmail.com> wrote in message
                  news:a60c0ad7.0 309102207.1a754 144@posting.goo gle.com...[color=blue]
                  > Josephine,
                  >
                  > I am sorry, if I did not ask the question clearly enough.
                  >[color=green][color=darkred]
                  > > > // NOTE: I am adding a char beyond the array boundary[/color]
                  > >
                  > > But why? You haven't allocated enough space to write another extra
                  > > character.
                  > > Strings do end with a null character but then you need to allocate space[/color][/color]
                  for[color=blue][color=green]
                  > > that null character
                  > > also. I hope you know that.[/color]
                  >
                  > Yes, I know that and I am overwriting the memory intentionally. I was[/color]
                  curious[color=blue]
                  > to know, how would a typical compiler handle such a case. Yes, the[/color]
                  behaviour[color=blue]
                  > is indeed undefined according to the language standards in such a case.[/color]
                  However,[color=blue]
                  > given a combination of Operating System and Compiler, the behaviour of the
                  > program will have an explanation and I was interested in that explanation.
                  > Maybe, this group is the wrong place to ask this question.
                  >[color=green]
                  > > Taking that into consideration -
                  > > char * arr = new char[value + 1];
                  > > char * next = new char[value + 1];
                  > > should be what would get you the desired result.
                  > > HTH,
                  > > J.Schafer[/color]
                  >[/color]
                  OK may be I can attempt to give you some insight on why your program crashes
                  sometimes.
                  Typically most architectures return on a suitable alignment for all types
                  when dealing with dynamic memory. Thus four bytes are atleast consumed in
                  practice (even in cases of zero byte allocation). Also implementation( s)
                  typically use an additional 4-byte word to record allocation sizes, so then
                  another four bytes are consumed.Such information is typically placed right
                  before the dynamically allocated item.
                  When you allocate on multiple of 4 bytes the alignment is proper .Thus when
                  you try to write past the allocated boundary, you could be attempting to
                  overwrite basically anything. This may/may not be the same in other cases.
                  Ofcourse I am just proposing one explanation. An implementation can do it
                  any way.

                  HTH,
                  J.Schafer



                  Comment

                  • Karl Heinz Buchegger

                    #10
                    Re: Getting Segmentation Fault, selectively, on memory overwrite.



                    Vishal Grover wrote:[color=blue]
                    >
                    > Josephine,
                    >
                    > I am sorry, if I did not ask the question clearly enough.
                    >[color=green][color=darkred]
                    > > > // NOTE: I am adding a char beyond the array boundary[/color]
                    > >
                    > > But why? You haven't allocated enough space to write another extra
                    > > character.
                    > > Strings do end with a null character but then you need to allocate space for
                    > > that null character
                    > > also. I hope you know that.[/color]
                    >
                    > Yes, I know that and I am overwriting the memory intentionally. I was curious
                    > to know, how would a typical compiler handle such a case.[/color]

                    The compiler doesn't handle anything in this case. What you overwrite,
                    and if it is vital to the whole system is more or less random and depends
                    on your exact program text, the state your operating system is in, if there
                    are other programs running, how low is the operating system on memory, etc.
                    Add a variable to your function and the symptoms may be different.
                    [color=blue]
                    > Yes, the behaviour
                    > is indeed undefined according to the language standards in such a case. However,
                    > given a combination of Operating System and Compiler, the behaviour of the
                    > program will have an explanation and I was interested in that explanation.[/color]

                    The only way to figure out what really happens in your case is to look
                    at the assembly output and do a carefull examination and a step through
                    through the program and hope that the environment your program runs in has
                    not changed to much, such that the symptoms are different.
                    [color=blue]
                    > Maybe, this group is the wrong place to ask this question.[/color]

                    It is.
                    This group has no answer for you, because in the context of this group
                    there doesn't exist an answer, except: undefined behaviour - anything can happen.


                    --
                    Karl Heinz Buchegger
                    kbuchegg@gascad .at

                    Comment

                    • Vishal Grover

                      #11
                      Re: Getting Segmentation Fault, selectively, on memory overwrite.

                      > >I compiled this with 3.2.2 on Red Hat Linux 9 on an Intel i686. When I run the[color=blue][color=green]
                      > >program, it gives me a Segmentation fault only when the array size is an odd
                      > >multiple of 4. My guess is it has something to do with word alignment. But, what
                      > >exactly is happening here?[/color]
                      >
                      > As others have answered, the only general answer is that you're invoking
                      > undefined behavior, where anything or nothing may happen.
                      >
                      > In practice it seems your compiled program is overwriting some allocation
                      > information.
                      >
                      > Such information is typically placed right before a dynamically allocated
                      > item. That seems to fit the alignment issue you have noted. It's no
                      > great mystery, but it has nothing to do with C++.[/color]

                      This seems a reasonable explanation. Thank you.
                      [color=blue]
                      > On the topic of C++, in order of appearance in the above code:
                      >
                      >
                      > * Guideline: don't use atoi, since it has no error checking.
                      > Exception: where you want 0 as result in case of error (add comment).
                      >
                      > * Guideline: don't use raw pointers and arrays, use smart pointers and
                      > standard library containers.
                      >
                      > * Guideline: avoid using a loop control variable after the loop.
                      >
                      > * Guideline: always execute a corresponding 'delete' for each 'new'.
                      >
                      > * Guideline: when you rely on the return value 'main' to indicate
                      > failure, express success explicitly by returning EXIT_SUCCESS.[/color]

                      Thanks again. Will keep in mind.
                      [color=blue]
                      >
                      > Finally, Word of Advice: don't take technical comments personally and
                      > threaten to "leave this list", as you seem to have done; see e.g.
                      > <url:http://www.winternet.c om/~mikelr/flame52.html>.[/color]

                      I admit, I am a newbie, and I have learnt a few things today.

                      Regards
                      Vishal

                      Comment

                      Working...