1

I'm developing the application, which will get mails from servers via pop/imap protocols using C++/Winsock.

Cause, the code is large to paste here , I give you the link on pastebin:
http://pastebin.com/uCKcTQsj

It doesn't have any compiler errors, so it can be copmpiled well.

I'm getting different result of its work, sometimes all working ok, but often I get the result:

Unhandled exception at 0x773f15de (ntdll.dll) in alex.exe: 0xC0000005:
Access violation reading location 0x00648000.

Why do I get different result of its work ( often cathing access violation, but sometimes it works )?

Are there any ways to catch and handle violation exceptions ( may be from lower secrity rings, as I understand , these exceptions are throwing from ntdll.dll in native mode ) to fix this problem?

Thanks, best regards!

Johan
  • 74,508
  • 24
  • 191
  • 319
  • 2
    http://msdn.microsoft.com/en-us/library/6dekhbbc(v=vs.80).aspx – BlackBear Jan 19 '12 at 19:43
  • 1
    how can I catch exception with try block, if this exception was thrown from lower security ring from ntdll.dll, this exc was thrown not from user-mode –  Jan 19 '12 at 19:51
  • 2
    You need to fix the problem by fixing bugs in the code, not by catching exceptions for invalid memory accesses. Running under a debugger and looking at the call stack for the exception will probably point you to most of your problem areas. – Michael Burr Jan 19 '12 at 19:56
  • 1
    yeah... under the debugger, I've got exception in ostream ( where I'm enumarating the char* buffer ) on returning the return (_Ostr); –  Jan 19 '12 at 20:15

2 Answers2

2

Access violation means that you're accessing memory that hasn't been allocated to your application.

You get random successes/failures because sometimes memory that you're trying to access will be allocated to your application, sometimes it won't be.

Either way, the problem is that you're trying to access memory that hasn't been malloced (or newed). I.e. you're either trying to dereference/write to/read from a "dangling" or "wild" pointer, or you're trying to read/write beyond the boundaries of a memory block a properly allocated pointer points to.

2

Your header struct contains this array:

char buffer[0x1000];

But you treat it as a null terminated C string in several places without making sure that it is actually null terminated.

For example, in Inet::GetResponse():

int result = recv((*sock), buffer, strlen(buffer), 0)

I don't think that strlen(buffer) will return anything meaningful. You probably should use sizeof(buffer).

But even when you're dealing with received data, there's no guarantee that the data will be null terminated - even if the protocol does terminate records with nulls. With TCP a recv() can return only part of a sent record, so even in situations where a null is sent, it might not be received yet. In particular, the POP3 and IMAP protocols do not terminate responses with a null octet. So unless you make sure the '\0' is there, strlen() and friends cannot be used.

You need to carefully reexamine how you're handling the buffer size and the amount of data received in that code.

Michael Burr
  • 333,147
  • 50
  • 533
  • 760
  • 1
    with sizeof() the same result :((( –  Jan 19 '12 at 19:54
  • 1
    I know, that some data may not be recieved yet, and that's why using Sleep() function to wait for incoming data. –  Jan 19 '12 at 20:06
  • 1
    That'll probably work most of the time, but you really should use the result returned by `recv()`. – Michael Burr Jan 19 '12 at 20:34
  • 1
    I was wondering what the comparison with `-52` was doing in `HandleResponse()` - you're depending on the compiler to 'initialize' the buffer with `0xCC` values. You realize that that's just a debugging helper - please don't write code that depends on that behavior (it depends on a specific compiler options being enabled, and won't generally occur in release builds). – Michael Burr Jan 19 '12 at 20:40
  • 1
    -52 is the value of empty char, if you create smth like char *buff; look at its content in the debugger, you can see only -52 values... –  Jan 19 '12 at 20:46
  • 1
    Finally - I mislead you about using `sizeof(buffer)` in `Inet::GetResponse()`. In the function, `buffer` is just a pointer, so the function doesn't know about the size of the `buffer` member in `Header`. Sorry about that; however, the key ideas from the answer still stand (that you need to reexamine how you're handling buffer sizes and response lengths). – Michael Burr Jan 19 '12 at 20:49
  • 1
    `-52` is not the value of 'empty char'. That's a debugging tool the compiler provides (sometimes - not always!) to help you find when you're using uninitialized memory. See http://stackoverflow.com/questions/370195/when-and-why-will-an-os-initialise-memory-to-0xcd-0xdd-etc-on-malloc-free-new for more details. – Michael Burr Jan 19 '12 at 20:53