Что вызывает эту ошибку: "адрес, уже известный ядру для другого [занятого] типа синхронизатора"?
У меня есть клиент, чей системный журнал заполняется тысячами копий этого сообщения:
25 июля, 11:21:33 athayer-mbp13 kernel[0]: PSYNCH: pid[52893]: адрес, уже известный ядру для другого [занятого] типа синхронизатора
Виновником является мое приложение, но я не могу воспроизвести проблему и не очень разбираюсь в ее причине. Мое приложение выполняет поиск на диске, и эта ошибка происходит через 15 часов после начала процесса. Нет чрезмерного использования памяти или утечки файлового дескриптора. Приложение продолжает работать нормально, просто эти сообщения приводят к тому, что системный журнал увеличивается до гигабайтных размеров и заполняет загрузочный диск.
Я нашел код ядра Дарвина, в котором напечатано сообщение, но это всего лишь подсказка, на нем не видно пистолета:
http://opensource.apple.com//source/xnu/xnu-1699.32.7/bsd/kern/pthread_support.c
FAILEDUSERTEST("адрес, уже известный ядру для другого (занятого) типа синхронизатора \n");
Именно в этой функции:
/* find kernel waitqueue, if not present create one. Grants a reference */
int
ksyn_wqfind(user_addr_t mutex, uint32_t mgen, uint32_t ugen, uint32_t rw_wc, uint64_t tid, int flags, int wqtype, ksyn_wait_queue_t * kwqp)
Может ли кто-нибудь дать представление о том, что происходит?
Вот профиль для машины:
Model Name: MacBook Pro
Model Identifier: MacBookPro12,1
Processor Name: Intel Core i5
Processor Speed: 2.7 GHz
Number of Processors: 1
Total Number of Cores: 2
L2 Cache (per Core): 256 KB
L3 Cache: 3 MB
Memory: 8 GB
Boot ROM Version: MBP121.0167.B16
SMC Version (system): 2.28f7
Hardware UUID: 9205D058-90BF-541E-8E61-E75259ABC11F
Обзор системного программного обеспечения:
System Version: OS X 10.11.4 (15E65)
Kernel Version: Darwin 15.4.0
Boot Volume: Macintosh HD
Boot Mode: Normal
Computer Name: athayer-mbp13
User Name: System Administrator (root)
Secure Virtual Memory: Enabled
system_integrity: integrity_enabled
Time since boot: 9 days 18:55
1 ответ
Возможное объяснение
Возможно, на вас повлияла ошибка старого ядра. Если переменная условия pthread (основной компонент стандарта pthread_mutex
Объект семьи) размещен, но никогда не ожидался, есть ситуация, в которой его объект никогда не удаляется из внутреннего реестра pthreads в OSX.
Если это произойдет, и если позже будет выделен другой мьютекс, который окажется в том же месте в памяти, и если этот мьютекс будет ожидаться, эта ошибка может произойти, поскольку идентификатор нового мьютекса не будет совпадать с идентификатором, уже присутствующим в его пространство. Это отличается от проблемы перераспределения, когда вместо действительного идентификатора находится искаженная / бессмысленная информация.
Временное решение
Обходной путь должен гарантировать, что вы вызываете функцию ожидания для всех мьютексов / condvars, которые вы создаете. Даже наносекундное ожидание вызовет "правильное" разрушение, когда оно завершится на уже не используемом мьютексе. Пример исправления разработчиками Chromium приведен ниже.
Например, вы можете подождать одну наносекунду / тик на блокировку таким образом:
struct timespec time { .tv_sec = 0, .tv_nsec = 1 };
pthread_cond_timedwait_relative_np(
&some_condition_handle,
&some_lock_handle,
time
);
Сопутствующие факторы
Ошибка в ядре не может быть реальной проблемой. Здесь много мешающих факторов:
- Исходный код ядра не был опубликован для 10.10 или 10.11, поэтому вызываемый код, который генерирует эту ошибку, может не совпадать с кодом, который вы нашли в Интернете.
- В результате, упомянутая выше ошибка в ядре может не существовать или быть недоступной таким же образом.
- В строке ошибки, которую вы опубликовали, есть символы (
()
) вокруг слова "занят", но источник, который вы нашли, имеет квадратные скобки ([]
). Места в коде, которые печатают два разных сообщения, отличаются друг от друга, поэтому проблемные строки могут не совпадать с теми, которые вы указали в своем вопросе.
Соответствующие ссылки
- Статья первого (единственного?) Человека, который поставил диагноз этой проблемы: http://rayne3d.com/blog/02-27-2014-rayne-weekly-devblog-4
- Проблема отображается в источнике pthread (или в pthread 105.1.4), видимом по этой ссылке (выполните поиск на странице для
13782056
): https://opensource.apple.com/source/libpthread/libpthread-105.1.4/src/pthread_cond.c - Пример исправления, подобного описанному выше обходному решению, был сделан командой Chromium, когда на них повлияла похожая (такая же?) Проблема: https://codereview.chromium.org/1323293005
- Исходная ссылка на форум для разработчиков Apple больше не существует, хотя я могу просто не получить к ней доступ: https://devforums.apple.com/thread/220316?tstart=0