Segfault при удалении раздела .gnu.version - PullRequest
0 голосов
/ 27 февраля 2019

Я нахожусь в процессе переписывания устаревшего кода на основе старого Framework с C ++ 11, используя библиотеки потоков и хронографических данных.Подводя итог, библиотека порождает поток и ожидает либо событие, либо задержку.

Моя проблема в том, что когда я удаляю двоичный файл, удаляя раздел .gnu.version, программа вызывает ошибки.Мне интересно, какова цель этого раздела и как извлечение его из двоичного файла может привести к другому поведению и вызвать segfault?


Я написал пример кода, который хорошо работает, пока я не удаляюсекция .gnu.version.

1.Компиляция

g ++ -std = c ++ 11 test.cpp -o test -pthread -lpthread

2.Исполнение перед полосой

$ ./test
>>run()
  run() - before wait()
>>wait()
< wait()
  run() - after wait()
  run() - before wait_until()
  run() - after wait_until()
  run() - before wait()
  run() - after wait()
< run()

3.Полоса .gn.version участок

полоса -R .gnu.version тест

4.Выполнение после полосы

 ./test
>>run()
  run() - before wait()
>>wait()
< wait()
  run() - after wait()
  run() - before wait_until()
Segmentation fault (core dumped)

Из того, что я смог исследовать, происходит ошибка в std::condition_variable::.wait_until() при вызове библиотеки pthread без задержки.

Вот пример кода:

#include <thread>
#include <iostream>
#include <condition_variable>
#include <unistd.h>

class Task
{
private:
    std::mutex _mutex;
    std::condition_variable _cv;
    std::thread _thread;
    bool _bStop;
    bool _bWait;

    void run()
    {
        std::unique_lock<std::mutex> lock(_mutex);
        std::cout << ">>run()" << std::endl;
        while (!_bStop)
        {
            if ( !_bWait )
            {
                std::cout << "  run() - before wait()" << std::endl;
                _cv.wait(lock);
                std::cout << "  run() - after wait()" << std::endl;
            }
            else
            {
                _bWait = false;
                std::chrono::steady_clock::time_point ts = std::chrono::steady_clock::now()
                                                         + std::chrono::seconds(1);
                std::cout << "  run() - before wait_until()" << std::endl;
                _cv.wait_until(lock,ts);
                std::cout << "  run() - after wait_until()" << std::endl;
            }
        }
        std::cout << "< run()" << std::endl;
    }

public:
    Task():_bStop(false),_bWait(false)
    {
    }

    void start()
    {
        _thread = std::thread(&Task::run,this);
    }

    void wait()
    {
        std::cout << ">>wait()" << std::endl;
        std::unique_lock<std::mutex> lock(_mutex);
        _bWait = true;
        _cv.notify_one();
        std::cout << "< wait()" << std::endl;
    }

    void cancel()
    {
        std::unique_lock<std::mutex> lock(_mutex);
        _bStop = true;
        _cv.notify_one();
    }

    void join()
    {
        _thread.join();
    }
};

int main()
{
    Task t;

    // Start Task thread
    t.start();

    // Sleeping here seems to help produce the error
    usleep(10000);
    t.wait();

    // Wait for Task to process delay
    sleep(5);

    // Stop Task and wait for thread termination
    t.cancel();
    t.join();

    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...