-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 18.09.2014 09:19, Valentin Hauner wrote:
Hi,
On 09/17/2014 04:31 PM, Björn Döbel wrote:
In the end means, that your stack mapping did not succeed as intended.
OK, that helped. Indeed, some of the arguments concerning the size of the area to map were wrong. Now, there is no page fault on the stack any more.
Yay!
Then, I got the following pf:
pf: 0026 pfa=affff800 ip=affff800 (r-) spc=0xfcffae94 err=4
Using objdump on my binary, I've found out that it has something to do with 'l4sys_invoke_direct'. In the end, I've mapped this address to the new task, and the page fault is gone. Is there any more elegant way to do this?
At this address L4Re applications by default have the "Kerne Info Page" mapped. The KIP contains information about the underlying kernel, a field for reading the current time (similar to Linux' vDSO) and the entry code for system calls. The page fault you are getting is because your program is executing its first system call and needs to read this code.
Simply mapping the creator's KIP to the same address in the new task will do the trick as you found out.
The next page fault I'm getting is this: pf: 0026 pfa=b1007f1c ip=01009980 (r-) spc=0xfcffae94 err=4 A call of addr2line on 0x01009980 gives me:
l4/pkg/uclibc/lib/uclibc/_exit.cc:14
I guess it's related with the call of exit at the end of my thread function.
void thread_func(l4_umword_t cap) { printf("Hello World!\n"); exit(0); }
Did you see the printf() output before?
If I remove that exit call, I will get a read page fault on pc=0 since the function tries to jump back to its caller, but there is no caller, so the address lying on the stack is 0.
How can I map all those library functions to my new task?
These functions are already there - you see this because your code actually reaches and executes the instruction at 0x1009980.
The problem you have is that you are starting an application on Fiasco.OC without the L4Re binary attached to your program. (Again, I'm still not getting, why you want to do this, but nevermind.)
When I have a look at the _exit() function you found, then what this function does is to send an exit signal to its L4Re parent. This concept does not exist in your setup and the access to the L4Re::global_env->parent member is probably what is causing your thread to raise a page fault.
Couple of solutions:
1) Use L4Re instead of rolling your own environment. 2) Do not call exit(), but have your threads simply do an infinite sleep(). You will see how this works in the implementation of _exit(), because this is what this function does as well. 3) Implement your own version of exit that notifies the creator so that the creator can perform the necessary cleanup work.
L4Re actually implements a combination of variants 2 + 3.
- From a semantic perspective: calling exit() in multithreaded programs is likely to not do what you intend. exit() terminates the running program regardless of what progress the other threads are making, it does NOT simply terminate a thread. (This is not L4-specific, this is what the POSIX standard says.)
Bjoern
- -- Dipl.-Inf. Bjoern Doebel Mail: doebel@tudos.org TU Dresden, OS Chair Phone: +49 351 463 38 799 Noethnitzer Str. 46 Fax: +49 351 463 38 284 01187 Dresden, Germany WWW: http://www.tudos.org/~doebel - -- "When the seagulls follow the trawler, it's because they think sardines will be thrown into the sea." (Eric Cantona)