Почему strace показывает ERESTARTSYS для чтения?

У меня есть многопоточная программа, которая при запуске через strace показывает это:

read(10, "lorem ipsum...", 100) = 100
read(10, 0x2ae9ebcb5000, 8191) = ? ERESTARTSYS (To be restarted)
--- SIGTERM ... ---

Всякий раз, когда возникает ошибка ERESTARTSYS, программа зависает при чтении. Когда ERESTARTSYS не происходит, программа успешно завершается, и я получаю:

read(10, "lorem ipsum...", 100) = 100
read(10, "", 8191) = 0
...
exit_group(0)

Глядя на strace справочную страницу (для strace, который не моя версия) и ТАК вопросы, как this и это, кажется, что чтение прерывается некоторыми сигнал. Я мог неправильно понять документ, но я не вижу никакого сигнала, кроме SIGTERM, который, как я предполагаю, исходит от моего выхода из программы.

Я определил, что два чтения происходят из вызова std::getline, который читается дважды, когда разделитель не найден (он не найден, потому что разделитель неверен и нигде в строке, но я не могу исправить это, потому что это находится в библиотеке, которую я не могу контролировать). Добавление разделителя в строку, по-видимому, предотвращает второе чтение, что приводит к тому, что код выполняется без проблем.

Я также уверен, что в коде есть какое-то состояние гонки, потому что, когда я отключаю параллелизм, эта ошибка не возникает. Одно из моих диких предположений заключается в том, что чтение прерывается во время переключения контекста потока, однако это всего лишь дикое предположение, и ничто в strace не указывает на то, что это правда. Кроме того, я не уверен, почему он просто не перезапустится после обратного включения. Однако я не могу найти условие гонки и надеялся, что понимание strace и ERESTARTSYS поможет мне понять, где ошибка. является.

Если это поможет, я использую RHEL5 и компилирую с помощью gcc 4.7.2.


person Lycus    schedule 08.08.2014    source источник
comment
Это странно, потому что ERESTARTSYS предполагается использовать только в ядре для прозрачной обработки. Ваше приложение не должно его видеть.   -  person tangrs    schedule 10.08.2014


Ответы (1)


Согласно этой ссылке, это происходит, когда чтение прерывается strace в системах RHEL. В коде, на который я смотрел, оказалось, что чтение просто зависло, ожидая ввода, потому что EOF не был найден и потому что все еще был открыт конец записи (из-за состояния гонки).

person Lycus    schedule 13.08.2014