What Is the Valid Address Space for a User Process? (Os X and Linux)

32-bit process’s address space on 64-bit linux

Citing the kernel source: “Kernel pointers have redundant information, so we can use a scheme where we can return either an error code or a [...] pointer with the same return value.

The values -1..-4095 (mapping to 0xfffff000–0xffffffff in 32-bit mode) are reserved for kernel-level errno values. The other 4KB from 0xffffe000–0xffffefff are held free for the vsyscall vdso magic page, but since the vdso page is relocatable since many moons, this area remains potentially unpopulated, that is to say, the [stack] entry in /proc/*/maps ends at 0xffffdfff always regardless of whether [vdso] is mapped at 0xffffe000 or elsewhere.

Strange address of a C variable in Mac OS X

When processes run in general-purpose operating systems, the operating system constructs a “virtual” address space for each process, using assistance from hardware.

Whenever a process with a virtual address space accesses memory, the hardware translates the virtual address (in the process’ address space) to a physical address (in actual memory hardware), using special registers in the hardware and tables in system memory that describe how the translation should be done.1 The operating system configures the registers and tables for each process.

Commonly, the operating system, or the loader (the software that loads programs into memory for execution) assigns various ranges of the virtual address space for various purposes. It may put the stack in one place, executable code in another, general space for allocatable memory in another, and special system data in another. These addresses may come from base locations set arbitrarily by human designers or from various calculations, or combinations of those.

So seeing a large virtual address is not unusual; it is simply a location that was assigned in an imaginary address space.

Footnote

1 There are additional complications in translating virtual addresses to physical addresses. When the processor translates an address, the result may be that the desired location is not in physical memory at all. When this happens, the processor notifies the operating system. In response, the operating system can allocate some physical memory, read the necessary data from disk, update the memory map of the process so that the virtual address points to the newly allocated physical memory, and resume execution of the process. Then your process can continue as if the data were there all along. Additionally, when the system allocated physical memory, it may have had to make some memory available by writing data that was in memory to disk, and also removing it from the memory map of some process (possibly the same one). In this way, disk space becomes auxiliary memory, and processes can execute with more memory in their virtual address spaces than there is in actual physical memory.

In virtual memory, can two different processes have the same address?

1)

  • Same physical memory address at the same time: NO
  • Same virtual memory address at the same time: YES (each one maps to differnet physical address, or swap space)

2) I think the debuggers don't access directly the other process debugged but communicates with the runtime in the debugged process to do that changes.

That said, maybe the OS or processor instructions provide access/modify to other's memory access if you have the right. That doesn't mean it has the SAME address, it only says process 1 can say "access memory @address1 in Process2". Someone (processor / OS / runtime) will do that for process 1.

Virtual address space in the context of programming

Can this grow upto 4GB?

The size of the address space is capped by the number of unique pointer values. For a 32-bit processor, a 32-bit value can represent 2 ^ 32 distinct values. If you allow each such value to address a different byte of memory, you get 2 ^ 32 bytes, which equals four gigabytes.

So, yes, the virtual address space of a process can theoretically grow to 4 GB. However in reality, this may also depend on the system and processor. As can be seen:

This theoretical maximum cannot be achieved on the Pentium class of processors, however. One reason is that the lower bits of the segment value encode information about the type of selector. As a result, of the 65536 possible selector values, only 8191 of them are usable to access user-mode data. This drops you to 32TB.

Note that there are two ways to allocate memory from the system, you can, of course, allocate memory for your process implicitly using C's malloc ( your question is tagged c ), but explicitly map file bytes.

Is there any limit on the number of processes in such a system?

a process includes one or more threads that actually execute the code in the process (technically, processes don’t run, threads do) and that are represented with kernel thread objects.

According to some tests carried out here, A 32-bit Windows XP system with 2GB of default address space can create approximately 2025 threads:

Thread Limit of 2025

However a 32-bit test limit running on 64 bit Windows XP with 4GB allocated address space
created close to 3204 threads:

32bit test limit on 64 bit XP created 3204 threads

However the exact thread and process limit is extremely variable, it depends on a lot of factors. The way the threads specify their stack size, the way processes specify their minimum working set, the amount of physical memory available and the system commit limit. In any case, you don't usually have to worry about this on modern systems, since if your application really exceeds the thread limit you should rethink your design, as there are almost always alternate ways to accomplish the same goals with a reasonable number.

Reasonable valid start address for mmap address hint so as to be gauranteed that things work

I don't think that anyone is going to be able to guarantee any address that will always work. The choice of virtual addresses is always up to the kernel and MAP_FIXED is always going to step on its toes.

Might I suggest not using -m32 to compile your application? With so many more addresses available you'll be 4294967296 times less likely to hit a conflict if you choose a random address.

I would suggest one of the following hacks:

  • Since you are on Linux, read and parse /proc/self/maps. Find the largest gap between any two mappings, and choose an address right at the midpoint of this gap. You should be reasonably safe in case the previous mapping creeps upward or the next mapping creeps downward in subsequent runs. Communicate this address to the other process so that it can try mapping at the same address. Hopefully the other process's memory map will be similar enough and it will have this big gap more or less at the same place.
  • Temporarily allocate a huge amount of anonymous memory without MAP_FIXED. For your fixed mapping, try the address immediately following this mapping. Communicate this address to the other process so that it can try mapping at the same address, and then get rid of the temporary mapping. Hopefully the other process's memory map will be similar enough and you've left yourself a huge amount of spare addresses before your chosen address so that if the second process is occupying some of those you will still be OK.

And keep in mind that these are hacks.



Related Topics



Leave a reply



Submit