[Search for users]
[Overall Top Noters]
[List of all Conferences]
[Download this site]
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 16: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.R | Title | User | Personal Name | Date | Lines |
---|
3599.1 | | SPECXN::DERAMO | Dan D'Eramo | Tue Jun 03 1997 18:25 | 36 |
| >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.2 | thanks | WRHS79::LANE | | Wed Jun 04 1997 09:02 | 6 |
| 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
|