Hi,
I try genode on fiasco and encounter a strange problem in core process. It seems that stack goes over heap. Here is some explanation : After a little while, init child thread from core (4.04) raises an exception into Server_activation_base::entry at _curr_obj->unlock(). After some debugging, I saw that _curr_obj (at 0x647a4) is modified during dispatch at a push assembler instruction. So, I guess, stack goes over the heap, isn't it ?
Regards Marc
Hello Marc,
thanks for the first real post on our mailing list! I am really happy that you are experimenting with our project.
I try genode on fiasco and encounter a strange problem in core process. It seems that stack goes over heap. Here is some explanation : After a little while, init child thread from core (4.04) raises an exception into Server_activation_base::entry at _curr_obj->unlock(). After some debugging, I saw that _curr_obj (at 0x647a4) is modified during dispatch at a push assembler instruction. So, I guess, stack goes over the heap, isn't it ?
Indeed, the current version of Genode locates stacks in the heap, which is generally a bad idea because this makes it really hard to detect stack overflows. Hence, we plan to change the stack- allocation scheme for the next release.
For solving your current problem, it would be helpful to be able to reproduce it. How do you trigger the bug and how does your config file look like? Could you provide us with the backtraces of Core's threads?
Best regards Norman
Norman Feske <norman.feske@...1...> writes:
Hello Marc,
thanks for the first real post on our mailing list! I am really happy that you are experimenting with our project.
I try genode on fiasco and encounter a strange problem in core process. It seems that stack goes over heap. Here is some explanation : After a little while, init child thread from core (4.04) raises an exception into Server_activation_base::entry at _curr_obj->unlock(). After some debugging, I saw that _curr_obj (at 0x647a4) is modified during dispatch at a push assembler instruction. So, I guess, stack goes over the heap, isn't it ?
Indeed, the current version of Genode locates stacks in the heap, which is generally a bad idea because this makes it really hard to detect stack overflows. Hence, we plan to change the stack- allocation scheme for the next release.
Is it possible to use a guard page to detect stack overflow? Having a way to implement guard pages using Bastei primitives would be nice for some other projects I have in mind.
Regards,
Hi Julian,
Julian Stecklina wrote:
Is it possible to use a guard page to detect stack overflow? Having a way to implement guard pages using Bastei primitives would be nice for some other projects I have in mind.
Our current plan is to use a dedicated area of the virtual address space to locate the stacks, for example each stack would reside within an 1MB area. Of this 1M range, only a few pages would actually be backed by RAM dataspaces. Therefore, we would have plenty of guard pages in-between the stacks. The current Genode mechanisms are already sufficient to implement such an allocation scheme (using a Range_allocator for managing the virtual stack area, and calling rm_session->attach() with specifying the 'local_addr' argument). This alone would certainly be an improvement over co- locating stacks with the heap.
However, once having such an allocation scheme in place, it would be useful to reflect (RM-session-) faults to the process (right now, faults are only indicated by a debug message from Core). I am thinking of adding a signalling mechanism to the RM-session. An RM-fault handler could then receive fault signals (analogous to an exception handler that gets invoked by page fault), request the cause of the fault (analogously to looking at an exception- stack frame), and attach a dataspace to the faulted address (analogously to setting a page-table entry). So functionality-wise, an RM-session would pretty much correspond to a page table, only that it is using dataspaces rather of physical pages. This would not just enable us to detect stack overflows and invalid memory accesses but it would make the implementation of dynamically growing stacks straight-forward.
At Thu, 14 Aug 2008 20:23:18 +0200, Norman Feske wrote:
Julian Stecklina wrote:
Is it possible to use a guard page to detect stack overflow? Having a way to implement guard pages using Bastei primitives would be nice for some other projects I have in mind.
Our current plan is to use a dedicated area of the virtual address space to locate the stacks
Why are you special casing stacks? Isn't using something like mmap enough?
This would not just enable us to detect stack overflows and invalid memory accesses but it would make the implementation of dynamically growing stacks straight-forward.
As far as I am aware, no one really does this as pthreads doesn't support this. The reason is straightforward: you essentially have to reserve the address space anyways since it is not generally possible to relocate the stack. If you don't, you have to crash when the thread tries to grow the stack and there is no address space available. How are you going to avoid this limitation? What are the advantages of this approach?
Neal
Hi Neal,
Neal H. Walfield wrote:
At Thu, 14 Aug 2008 20:23:18 +0200, Norman Feske wrote:
Julian Stecklina wrote:
Is it possible to use a guard page to detect stack overflow? Having a way to implement guard pages using Bastei primitives would be nice for some other projects I have in mind.
Our current plan is to use a dedicated area of the virtual address space to locate the stacks
Why are you special casing stacks? Isn't using something like mmap enough?
Sorry, maybe my explanation was a bit misleading. The mechanism is based on something like mmap (we attach a dataspace to the region map of the process). The addition I mentioned was the signalling mechanism that is missing right now. Regarding the stack allocation, I was just suggesting a user-level policy of where to place stacks within the processes address space. Just for clarity and debugging, it would be nice to have a convention, for example: all stack live in the area 0x40000000 to 0x80000000, each having a maxumum size of 0x100000. When I spoke of dynamically growing stacks, I meant growth only within the bound of 0x100000 minus one page (as a guard). I agree that relocating stacks during the lifetime of a thread sounds like an awkward idea ;-)
At Mon, 18 Aug 2008 15:28:18 +0200, Norman Feske wrote:
Regarding the stack allocation, I was just suggesting a user-level policy of where to place stacks within the processes address space. Just for clarity and debugging, it would be nice to have a convention, for example: all stack live in the area 0x40000000 to 0x80000000, each having a maxumum size of 0x100000.
This sounds like an issue for the threading library and nothing that needs to be exposed formally. FWIW, the traditional default stack size has been 8 MB.