[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::c_plus_plus

Title:C++
Notice:Read 1.* and use keywords (e.g. SHOW KEY/FULL KIT_CXX_VAX_VMS)
Moderator:DECCXX::AMARTIN
Created:Fri Nov 06 1987
Last Modified:Thu Jun 05 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:3604
Total number of notes:18242

3599.0. "stack corruption example (VMS)" by WRHS79::LANE () Tue Jun 03 1997 19:23

Hi,

I think I've run into a bug in CXX V5.5 on VMS.  Can someone tell me if this is
a known problem?  Hopefully, you'll be able to reproduce the behavior I'm
seeing.

thanks,

Roy

----------------------

Here's a small program that uses a "LineString" class, which is inherited from
the String class and has the "istream extraction >>" operator overloaded.
The >> is supposed to extract characters up to but not including the newline
(extract a line).

This program access violates on VMS, but runs successfully on UNIX (both are
CXX V5.5).

What I noticed about the VMS version that's different from the UNIX version
is that the VMS version calls the LineString assignment operator just before
returning from the ">>" routine.  This doesn't make sense to me because the
LineString object is being passed by reference and is not being returned as
the function value, so there should be no need to make this call.

Here's the module containing the main() routine:

#include <fstream.h>
#include <stdlib.h>
#include "linestring.hxx"

main(unsigned int argc, char *argv[])

{
    ifstream inStream;

    inStream.open(argv[1]);

    if (!inStream)
    {
        cerr << "? " << argv[1] << " - can't open file\n";

        return (EXIT_FAILURE);
    }

    LineString str;

    inStream >> str;

    cout << str << endl;

    return (EXIT_SUCCESS);
}

--------------------------------------------------------------------------------
Here's linestring.hxx:

#ifndef LineString_HXX
#define LineString_HXX

#include <String.hxx>

class LineString : public String
{
    public:
        friend istream& operator>>(istream& inStream, LineString& str);
        LineString() : String() {}
        LineString(const LineString& str) : String(str) {}
        LineString(const String& str) : String(str) {}
        LineString(const char* str) : String(str) {}
        LineString(const char& str) : String(str) {}
};

#endif

--------------------------------------------------------------------------------
Here's linestring.cxx containing the extraction operator function:

#include "linestring.hxx"

istream& operator>>(istream& inStream, LineString& str)

{
    static const unsigned int bufferSize = 1024;
    char buffer[bufferSize];
    unsigned int length = 0;

    buffer[bufferSize] = '\0';

    str = ""; // assignment op called here (expected)

    while (inStream.get(buffer[length++]) && (buffer[length - 1] != '\n'))
    {
        if (length == bufferSize)
        {
            str += buffer;

            length = 0;
        }
    }

    if (--length)
    {
        buffer[length] = '\0';

        str += buffer;
    }

    return (inStream);
}                             // assignment op called here (unexpected)
                              // debugger's SHO CALL references the
			      // str = ""; line for some reason.  Why is
			      // it calling the assignment function here?
			      // This results in ACCVIO because "this" is
			      // bogus.
T.RTitleUserPersonal
Name
DateLines
3599.1SPECXN::DERAMODan D'EramoTue Jun 03 1997 21:2536
>Can someone tell me if this is a known problem?
        
        In a sense, yes.
        
>    static const unsigned int bufferSize = 1024;
>    char buffer[bufferSize];
>    unsigned int length = 0;
>
>    buffer[bufferSize] = '\0';

        You can never declare an array of N elements and then assign to
        the element with index N.  You can only assign to the elements
        with index 0 through N-1.  [Here N is bufferSize.]
        
        Dan
        
           <<< TURRIS::DISK$NOTES_PACK:[NOTES$LIBRARY]DECC.NOTE;1 >>>
                                   -< DECC >-
================================================================================
Note 1664.2               finding stack corruption bugs                   2 of 5
CSC32::D_DERAMO "Dan D'Eramo, Customer Support Cent" 13 lines   7-FEB-1996 17:23
--------------------------------------------------------------------------------
        On OpenVMS Alpha, it appears that the return address in R26 is
        saved on the stack adjacent to one of your locals.  If that
        local is a char array and you overwrite it by one byte then
        when your function returns it could return to the wrong address.
        My favorite example had a printf repeatedly called in a small
        program with no looping (because the return from main returned
        there).
        
        The CSC put an example into STARS showing how to use asm() to
        look up the saved R26 before you corrupt it and periodically
        check it during the function before returning.
        
        Dan
        
3599.2thanksWRHS79::LANEWed Jun 04 1997 12:026
You caught me red-handed (and red-faced)...  I should have known it was my
problem - it was too basic to see it myself.

thanks,

Roy