libc: don't take alien thread for main pthread

It covers bugs which we should detect and fix, especially depending on
the result of pthread_myself locking implementation (ours and vbox) takes
decision to take a lock or just to assume it is a reentrant locking attempt.

Fixes #1128
This commit is contained in:
Alexander Boettcher 2014-04-09 15:47:26 +02:00 committed by Norman Feske
parent b9cf2eade8
commit 8824ce8962
5 changed files with 45 additions and 18 deletions

View File

@ -38,3 +38,5 @@ build_boot_image {
append qemu_args " -nographic -m 64 "
run_genode_until "--- returning from main ---" 10
puts "Test succeeded"

View File

@ -25,8 +25,6 @@
using namespace Genode;
static const bool verbose = false;
extern "C" {
/* Thread */
@ -71,25 +69,36 @@ extern "C" {
pthread_t pthread_self(void)
{
static struct pthread_attr main_thread_attr;
static struct pthread main_thread(&main_thread_attr, 0, 0, 64*1024,
"main", nullptr);
Thread_base *myself = Thread_base::myself();
/* the main thread does not have a Genode thread object */
if (!myself)
return &main_thread;
pthread_t pthread = dynamic_cast<pthread_t>(myself);
if (pthread)
return pthread;
if (!pthread) {
if (verbose)
PDBG("pthread_self() possibly called from alien thread, returning &main_thread.");
return &main_thread;
/* either it is the main thread, an alien thread or a bug */
/* determine name of thread */
char name[Thread_base::Context::NAME_LEN];
myself->name(name, sizeof(name));
/* determine if stack is in first context area slot */
addr_t stack = reinterpret_cast<addr_t>(&myself);
bool is_main = Native_config::context_area_virtual_base() <= stack &&
stack < Native_config::context_area_virtual_base() +
Native_config::context_virtual_size();
/* check that stack and name is of main thread */
if (is_main && !strcmp(name, "main")) {
/* create a pthread object containing copy of main Thread_base */
static struct pthread_attr main_thread_attr;
static struct pthread main(*myself, &main_thread_attr);
return &main;
}
return pthread;
PERR("pthread_self() called from alien thread named '%s'", name);
return nullptr;
}
@ -359,7 +368,6 @@ extern "C" {
if (!attr)
return EINVAL;
PDBG("not implemented yet");
*attr = 0;
return 0;
@ -452,7 +460,7 @@ extern "C" {
* logs a warning if the timeout is lower than the minimum. To
* prevent the warning, limit timeouts to >= 10 ms here.
*/
if (timeout != 0) timeout = max(timeout, 10);
if (timeout != 0) timeout = max(timeout, 10U);
c->signal_sem.down(timeout);
} catch (Timeout_exception) {
result = ETIMEDOUT;

View File

@ -50,6 +50,18 @@ extern "C" {
_attr->pthread = this;
}
/**
* Constructor to create pthread object out of existing thread,
* e.g. main Genode thread
*/
pthread(Thread_base &myself, pthread_attr_t attr)
: Thread_base(myself),
_attr(attr), _start_routine(nullptr), _arg(nullptr)
{
if (_attr)
_attr->pthread = this;
}
void entry()
{
void *exit_status = _start_routine(_arg);

View File

@ -65,7 +65,11 @@ int main(int argc, char **argv)
{
printf("--- pthread test ---\n");
printf("main thread: running, my thread ID is %p\n", pthread_self());
pthread_t pthread_main = pthread_self();
printf("main thread: running, my thread ID is %p\n", pthread_main);
if (!pthread_main)
return -1;
Thread thread[NUM_THREADS];

View File

@ -42,3 +42,4 @@ blk_cache
rump_ext2
virtualbox_auto_disk
thread
pthread