-
August 10th, 2005, 12:38 PM
#1
Can you do an explicit Stack Check in C++
I'm having some problems with a program and I suspect that the stack may be getting corrupted. Is there any way to explicitly do a stack check, to check its integrity?
-
August 10th, 2005, 01:10 PM
#2
Re: Can you do an explicit Stack Check in C++
There seems to exist no way to check the stack that I know of...
But, what makes you think your stack is corrupted?
What are you doing?
-
August 10th, 2005, 01:34 PM
#3
Re: Can you do an explicit Stack Check in C++
Do you own each function that is being called?
You could insert a sentinel value at the beginning of each function, and check it at the end. i.e.
void func()
{
int iCheckStack = 0x12345678;
// do rest of the stuff in your function
// then at the end:
ASSERT(iCheckState == 0x12345678);
}
There's a chance it might catch where the corruption is happening - if the value is corrupted it means someone below you in the call stack corrupted it. Then you could look at the content of the memory that was corrupted to try to guess who did it.
-
August 10th, 2005, 04:15 PM
#4
Re: Can you do an explicit Stack Check in C++
I'm looking at stack corruption since, frankly, I've been debugging a weird problem for several days and am just about out of ideas.
It deals with CSockets (and, yes, I know that's an issue for the Networking forum but I didn't get any resposes from that forum).
The situation is this:
I have a client program and a server program both running at the same time via the Visual Studio IDE.
The Client, using a CSocket, establishes a connection to the Server. The Client sends some info to the Server, the Server receives and interprets it as a command to do something, the Server does it and returns a bunch of data to the Server.
And all is well in software land.
But on the next attempt to do the very same thing (still running the same programs, right after the successful connection and transfer of data) the Client enters the CSocket::Connect method (to establish another connection), the Server enters and successfully returns from its CSocket::Accept (thereby establishing the connection), the Server sets up its CArchive objects for receiving and sending, and enters the CArchive::ReadString in anticipation of getting the string (the command) from the Client.
And then it stops.
The Client never returns from the CSocket::Connect (so that it can actually perform the sending of the data (command string) to the Server).
The Server never returns from the CArchive::ReadString, since the Client hasn't sent the string (it can't, since it hasn't returned from the CSocket::Connect);
So it's locked up and everything stops.
Oddly, if the transfer of data back to the client is just a little bit of data (a few strings) it all works just fine, screaming along at top speed, doing one transfer after another (hundreds of transfers). But if the Server transfers a whole bunch of data each time, then it encountersthis lockup problem.
Suggestions are desparately needed.
- Roger
-
August 10th, 2005, 04:20 PM
#5
Re: Can you do an explicit Stack Check in C++
I haven't used Sockets ever so I cant recommend a correction with those.
What I can tell you is that this seems to have little to do with Stack Corruptions.
Hence, you must focus your energies on solving this socket deadlock and forget Stacks for the meanwhile...
-
August 10th, 2005, 04:29 PM
#6
Re: Can you do an explicit Stack Check in C++
Some additional info...
It appears to me that what's happenning is that,in the timeslicing between the two programs, it's failing to get back to the Client program to complete the processing of the CSocket::Connect.
But why that should happen only when a prior connection transferred a bunch of data (as opposed to just a small bit of data) has me baffled.
These symptoms do not only occur when running via the Visual Studio IDE, they also occur when just running the programs by themselves, so that would seem to eliminate and oddities of the IDE causing the problem.
-
August 10th, 2005, 04:31 PM
#7
Re: Can you do an explicit Stack Check in C++
Stack is not a reason for this.
As your thread title would keep many of those that know CSockets well from visiting it, I would recommend you to to create a new thread appropriately titled with the subject matter describing this erratic behaviour you experience.
-
August 10th, 2005, 04:32 PM
#8
Re: Can you do an explicit Stack Check in C++
Siddhartha,
I have indeed been tackling the lockup issue from a CSockets perspective. It was after I had exhausted that avenue of attack (and myself) that I started looking at other possibilities, like stack corruption.
At the moment I'm just bewildered.
- Roger
-
August 10th, 2005, 04:36 PM
#9
Re: Can you do an explicit Stack Check in C++
Originally Posted by RogerGarrett
I have indeed been tackling the lockup issue from a CSockets perspective. It was after I had exhausted that avenue of attack (and myself) that I started looking at other possibilities, like stack corruption.
I understand your exasperation, Roger.
But, stack is not the problem.
You have mentioned that CSockets worked with Strings, and that it also worked with many strings, right?
Have you tried sending -
- One very long string (approximately the size of the non-string objects you intend sending?)
- Type-casting your object to a string, and reverse type-casting at the receiver's end? (Just for experiment's sake?)
-
August 10th, 2005, 04:46 PM
#10
Re: Can you do an explicit Stack Check in C++
Can you post the code (maybe with the non sockets bits stripped if its big)?
(This is a silly question, but.... you are using SOCK_STREAM and not SOCK_DGRAM?)
Dave Mclelland.
-
August 10th, 2005, 04:51 PM
#11
Re: Can you do an explicit Stack Check in C++
i know its off the topic now but some idea to "check" stack.
you can check the ESP register before and after calling a function (that you suspect that ruins the stack) something like:
Code:
:
DWORD BeforeAddr=0,AfterAddr=0;
_asm mov BeforeAddr,esp
// func that might ruin stack?
Func1();
_asm mov AfterAddr,esp
if ( BeforeAddr != AfterAddr )
{
// stack might be ruined
}
_asm mov BeforeAddr,esp
// func that might ruin stack?
Func2();
_asm mov AfterAddr,esp
if ( BeforeAddr != AfterAddr )
{
// stack might be ruined
}
//and so on where ever you want in the code
:
another idea to see what is going on is to use the _penter that will call the :
Code:
void __declspec(naked) _cdecl _penter( void );
before calling each function in your code and in there you can put some logging to know which function was the last that entered before ruining the stack/memory.
Cheers
-
August 10th, 2005, 04:59 PM
#12
Re: Can you do an explicit Stack Check in C++
GolanShahar: When ESP's BeforeAddress != AfterAddress on execution of a function you will anyways get a very visible (non-ignorable, glaring) Stack Fault...
-
August 10th, 2005, 05:06 PM
#13
Re: Can you do an explicit Stack Check in C++
Sid, you are right
but i dont think you could tell which function created the stack fault i think the message will just let you know which module caused it...correct me if i am wrong..?
Cheers
-
August 10th, 2005, 05:12 PM
#14
Re: Can you do an explicit Stack Check in C++
I find the thought interesting...
A stack fault exception would occur before function returned to the caller and hence, before you could check on ESP (this very check is implicitly done, and it is the very check that perhaps throws the exception.)
-
August 11th, 2005, 10:44 AM
#15
Re: Can you do an explicit Stack Check in C++
Regarding the original problem that prompted my question about stack corruption, I've put together the very simplified CSocket code that's causing the problem. Interestingly, after I simplified it, now I get the hang up problem all the time, regardless of how much data I'm transmitting.
I'll also post this in the Networking forum, but since a couple of you kind fellows have already looked at my problem in here, I'm posting it in here so that you might share your wisdom with me.
Here's the situation:
I have a client program and a server program. I start them both up, assuring
that the server starts up first and is waiting and ready for the client.
When the client program is started it successfully makes a connection to the server,
sends a simple string to the server, and then tries to ReadString from the
Server, on the assumption that the server got the string from the Client and
sends a string back to the Client.
The Server does indeed Accept the connection from the Client, successfully sets
up the sending and receiving Archives, and then does the ReadString, expecting to
read the string that was sent by the Client. But it never gets the string. It waits
forever inside the ReadString.
So, the Client is left hanging, waiting for a response from the Server,
while the Server is left hanging, never getting the string sent (supposedly
successfully) from the Client.
And there it waits, never completing the operations.
The code below shows the basic, stripped-down versions of the client and server programs.
What am I doing wrong?
Code:
// CLIENT CODE
AfxSocketInit();
CSocket ClientSocket;
int nPortNumberClient = 0; // 0 means for MFC to select an available port
if (ClientSocket.Create(nPortNumberClient))
{
int nPortNumberServer = 49153;
// Connect to the Server
if (ClientSocket.Connect("68.171.26.117", nPortNumberServer))
{
CSocketFile SocketFile(&ClientSocket);
CArchive ArchiveSending(&SocketFile, CArchive::store);
CArchive ArchiveReceiving(&SocketFile, CArchive::load);
// Send "GiveMeData" to the Server
ArchiveSending.WriteString("GiveMeData");
ArchiveSending.Flush(); // to assure sending of the data.
// Get response from Server
CString strResponse;
ArchiveReceiving.ReadString(strResponse); // <<< GETS TO HERE AND STOPS
ArchiveReceiving.Close();
ArchiveSending.Close();
SocketFile.Close();
}
else
{
TRACE("CLIENT Connection failure, timeout, perhaps?\n");
}
}
else
{
// Failed to Create the CSocket.
}
and here's the server code
Code:
// SERVER CODE
AfxSocketInit();
CSocket SocketServer;
int nPortNumberServer = 49153;
if (SocketServer.Create(nPortNumberServer, SOCK_STREAM, "68.171.26.117"))
{
if (SocketServer.Listen(5))
{
while (TRUE)
{
// Accept the connection.
CSocket sockRecv;
if (SocketServer.Accept(sockRecv))
{
// Create a file object
CSocketFile file(&sockRecv);
// Create a receiving stream.
CArchive ArchiveReceiving(&file, CArchive::load);
// Create a sending stream.
CArchive ArchiveSending(&file, CArchive::store);
.. Get string that was sent from Client
CString strCommand;
ArchiveReceiving.ReadString(strCommand); // GETS TO HERE AND STOPS
// In response to string from Server, send somtheing back to Client
ArchiveSending.WriteString("Data");
ArchiveReceiving.Close();
ArchiveSending.Flush();
ArchiveSending.Close();
}
else
{
// Failed to accept the connection
}
}
}
else
{
// Failed to listen
}
}
else
{
// Failed to create the main socket
}
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|