8

Sometimes bugs can cause memory access violation exception.

How exactly this exception is triggered? What mechanism works behind the scenes?

Does it need support from the CPU (starting at what CPU?) / from the OS (starting at what version?) / from the compiler (starting at what version?)

Edit:

One specific scenario I want to understand better:

The following code may cause an access violation exception.

TCHAR* czXXX= _T("ABCDEFG");
czXXX[0]= 'A';

I guess czXXX points to a read-only memory block, but what exactly happens?

Lior Kogan
  • 19,919
  • 6
  • 53
  • 85

6 Answers6

12

Memory access violations are a large topic :)

The Protection of Information in Computer Systems (from 1973 :) lays out of a mechanism of segments, where processes are allocated a base and a bound; any attempt to access memory outside the range base:base+bound meant the program had done something silly and should be killed.

The 80x86 line of processors implement basic segment support, and the GEMSOS security kernel is an A1-certified operating system kernel based on this mechanism.

But segments aren't very dynamic, and almost all modern operating systems are paging systems, that page in memory when it isn't available. This relies on the CPU having an MMU, memory management unit, that checks all memory accesses for correct privileges and presence/absence of the correct memory mapping. When a process tries to access memory that isn't currently mapped into RAM, the MMU signals the CPU that a fault has occurred, and the CPU suspends the process to load the requested memory page from disk. (Or, if the memory should not be mapped for the process, say it tries to access 0x0 or some random memory location that hasn't been mapped with mmap or similar memory allocating primitives, it kills the process.)

Intel's 80386 was the first Intel chip to support paging, which is why Windows 3.1's "386 Enchanced Mode" was so much better than the 286 mode.

Compilers aren't really involved, but the CPU, MMU, and operating system kernel must all work together.

sarnold
  • 102,305
  • 22
  • 181
  • 238
  • 1
    what if RAM and Disk both full? – Scott 混合理论 Sep 21 '15 at 07:20
  • 1
    @Scott混合理论 it is normal for RAM to be full, or very nearly full -- unused RAM is wasted RAM. Since performance degrades the more the computer must use swap space, normally people will try to run only as much software as will fit into memory. Once swap space is full, the kernel will start returning errors for memory allocations or will kill entire processes to free up space. Look for "OOM Killer" for details on that. – sarnold Sep 21 '15 at 17:09
7

In x86 architecture (and most others as well), this is started from the MMU - the Memory Management Unit. The MMU is used to translate virtual memory addresses to physical memory addresses. If a request is made to access an invalid address (0x00000000 or something too high) the MMU will trap (interrupt) to the OS (this is in fact done for every access not in the TLB (Translate Lookaside Buffer - the MMU translation "cache")). Here the OS will be able to tell that this is an illegal memory access, and propagate to the user application via the OS-dependent mechanism (signals in Linux (SIGSEGV), I'm not familiar with Windows enough to say how it is done in it).

This feature is available for any modern CPU, OS and compiler. The most basic requirement is an MMU, which is present in all but the most basic embedded CPUs. I doubt there is any PC currently operating that doesn't support this.

Edit:

Following the OP edit, when a literal string is used, the memory is placed in the .text segment of the executable. This is where the binary code and constant values sit. Naturally, in most OSs this is read-only (especially under Linux with various security enhancements). When you try to change a value of a literal string you are basically trying to write to a read-only memory, causing an access violation. Again, this is caught by the MMU that sees a write command to a read-only memory address.

Eli Iser
  • 2,788
  • 1
  • 19
  • 29
  • 2
    The OS-dependent mechanism is called "structured exceptions" in Windows: http://msdn.microsoft.com/en-us/library/ms680657%28v=vs.85%29.aspx – sbk Jan 30 '11 at 10:13
2

When you try to access a memory address, the computer goes through several steps:

  • If the address is part of the current memory segment, access is granted.
  • Otherwise, if the address's segment is in memory with appropriate access permission, access is granted.

If the address is not in memory, the CPU will generate a memory check exception. At this point, the operating system takes over.

  • If the segment is available in virtual memory with appropriate access permission, it is loaded into memory and assigned to the virtual memory manager; access is then granted.

If, at this point, the memory is not available, there is one of two possibilities. Either the address is not available, or you do not have the permissions you need (eg, trying to write into read-only memory). In this case, the operating system will pass the access violation to the process.

As to CPU and OS versions, this is any system that allows virtual memory. I don't know the details of this.

Kevin Lacquement
  • 5,057
  • 3
  • 25
  • 30
2

All of these answers explain what happens at a processor level very well. As mentioned, once the processor raises an interrupt to the os, then things change with different operating systems.

Windows uses a mechanism known as "Structured exceptions". Very important not to confuse this with C++ exceptions, they are different. Structured exceptions conceptually work in the same way as C++ exceptions, in that they unwind the stack looking for a handler. Since Structured Exceptions are language agnostic, they do not call destructors or do any cleanup.

Structured Exceptions can be caught with

__try
{
  //Usual code
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
  //Handling code
}
__finally
{
  //Cleanup
}

Be warned however, that once you get a Structured Exception, your program has already crashed, so there is no sane way to 'recover'.

More information on SEH.

Ramon Zarazua B.
  • 7,195
  • 4
  • 22
  • 26
1

Memory access violation may occur here also:

delete pSample;

//again deleting the same memory!
delete pSample;

For such cases, exception is raised from the memory model of the OS. Mostly it's the OS whose job is to validate the memory access from any process!

Nawaz
  • 353,942
  • 115
  • 666
  • 851
0
void Kaboom()
{
    int* certain_death = NULL;
    *certain_death = 0;
}
Marlon
  • 19,924
  • 12
  • 70
  • 101