Android + Pthread + C ++ = SIGSEGV - PullRequest
       6

Android + Pthread + C ++ = SIGSEGV

4 голосов
/ 05 апреля 2011

Следующий код компилируется и работает на стандартном Linux:

#include <iostream>
#include <pthread.h>

using namespace std;

class Foo
{
    public:
        Foo();
        void go_thread();
        void stop_thread();
    private:
        static void* worker( void* param );
        pthread_t m_pt;
};

Foo::Foo()
{
    m_pt = 0;
}

void Foo::go_thread()
{
    int success = pthread_create( &m_pt, NULL, worker, static_cast<void*>(this) );

    if( success == 0 )
    {
        cout << "thread started" << endl;
    }
}

void Foo::stop_thread()
{
    int success = pthread_join( m_pt, NULL );

    if( success == 0 )
    {
        cout << "thread stopped" << endl;
    }
}

void* Foo::worker( void* p )
{
    cout << "thread running" << endl;
    return 0;
}

int main()
{
    Foo f;
    f.go_thread();
    f.stop_thread();
    return 0;
}

и выдает следующий вывод:

$ ./a.out
thread started
thread running
thread stopped
$

Этот код также собирается с Android NDK (r5b). Тем не менее, когда я отправляю полученный исполняемый файл на устройство и запускаю его, я получаю SIGSEGV до того, как main () запустится. Я выделил проблему до pthread_create(). Кажется, простое существование этого вызова в моем коде, не говоря уже о выполнении, заставляет мою прогу вызывать ошибку. Есть идеи?

Ответы [ 2 ]

6 голосов
/ 05 апреля 2011

Возможно, это не так, но попробуйте заставить функцию, вызываемую pthread, создать нормальную функцию c (т.е. объявить ее как extern "C"), а не статическую функцию-член:

Это потому, что техническисоглашение для статических членов может отличаться от соглашения о вызовах C, которое используется библиотекой pthread C-библиотеки (хотя во многих случаях они одинаковы (именно поэтому он работает на вашем Linux-компьютере), на мой взгляд, не стоитриск портирования).

extern "C" void* start_the_thread(void*);

void* start_the_thread(void* data)
{
    Foo*  theObject = static_cast<Foo*>(data);
    // In Java if your Foo had been derived from Runable
    // This is s where theObject->run() would have been called.
    return Foo::worker(data);
}

int success = pthread_create( &m_pt, NULL, start_the_thread, static_cast<void*>(this)
1 голос
/ 05 апреля 2011

Кажется, проблема в сочетании iostream с pthread. Я прошел и заменил все койки на printf (), удалил предложение using и удалил заголовок iostream. Код скомпилирован и запущен без проблем на устройстве. Интересно, стоит ли об этом знать Google?

Окончательный (рабочий) код выглядит так:

#include <pthread.h>
#include <stdio.h>

class Foo
{
    public:
        Foo();
        void go_thread();
        void stop_thread();
    private:
        static void* worker( void* param );
        pthread_t m_pt;
};

Foo::Foo()
{
    m_pt = 0;
}

void Foo::go_thread()
{
    int success = pthread_create( &m_pt, NULL, worker, static_cast<void*>(this) );

    if( success == 0 )
    {
        printf( "thread started\n" );
    }
}

void Foo::stop_thread()
{
    int success = pthread_join( m_pt, NULL );

    if( success == 0 )
    {
        printf( "thread stopped\n" );
    }
}

void* Foo::worker( void* p )
{
    printf( "thread running\n" );
    return 0;
}

int main()
{
    Foo f;
    f.go_thread();
    f.stop_thread();
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...