简体   繁体   中英

In C, working in Linux, when will accessing arrays out of bounds cause a seg fault?

If I access an array out of bounds in Linux, (and Windows, and probably everything, but I feel I should be clear), I can sometimes access the memory there and sometimes it just immediately segfaults. I'm wondering what is the condition for the segfault, and why doesn't it get triggered all the time? Here is my guess, if someone can confirm or deny:

The memory is allocated to the process with page granularity, which would be 4KiB on the x86 (32 bit anyway, not sure about 64 bit). Therefore, I should theoretically be able to access anything beyond my array as long as I stay within that current page and no exceptions will even be raised.

Next, if I do access beyond that 4KiB boundary, it's possible that I'm accessing memory that already belongs to the program and is nicely mapped to an actual physical memory location in my virtual address space. Once again, no problems happen since that memory is mine in the first place (well, problems happen in that I'm accessing out of bounds, but no OS exceptions occur).

On the other hand, if my array access tries to access the restricted kernel portion of my process, I get a segfault exception even though it's memory that is mapped to physical memory.

Finally, if I'm trying to access memory that exists in the virtual address space but not the physical yet, I have two cases:

1) I'm extremely unlucky and I've just so happened to address a piece of memory for which a valid page exists in secondary storage, so the page fault exception just loads the new page and I can keep accessing out of bounds

2) Probably way more likely, I try to access a piece of memory in the virtual address space for which there is no valid page, so NOW the MMU throws the seg fault.

Is any of that right? Are there more conditions?

You covered most of it. The only other things I can think of are related to general protection faults ex: you went over your page boundary and even though that page is valid and mapped, it isn't marked as readable/writable, the page contains code not data, etc...

There's a whole sequence of events that takes place. The abomination that is the C programming language (and its derivatives) does not do range checking on arrays.

(For now assume you are doing an access outside the array bounds)

Because memory management is based on pages, anything access the memory in any way allowed by the array's actual memory as long as you do not go over a page boundary.

If you do go over a page boundary, the processor has to go to the page tables

  1. There may not be a page table entry for the page. => Access Violation
  2. There may be a page table entry for the page and it is not mapped. => Access Violation
  3. The page may be restricted to a higher access mode (eg Kernel, Supervisor, Executive). If so => Access violation.
  4. You may attempt to access the page in a manner not permitted (eg write to a read only page). If so => Access violation

If the logical page you attempt to access has a mapping and you attempt to access it in a manner allowed, you can hang yourself in C that way.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM