Сообщения консоли Cocoa / OSX: Не удалось настроить специальный порт задачи Mach 9: (os / kern) нет доступа - PullRequest
0 голосов
/ 27 апреля 2011

У меня есть приложение для сбора данных (напряженность магнитного поля Земли), которое имеет четыре фазы;они запускаются через cron с интервалами 2,3,4 и 5 минут, упорядоченные так, чтобы все необходимое для одного шага было собрано до того, как это произойдет.

Из-за интервалов я не могу, поскольку японять это, использовать launchd для запуска фаз;следовательно, я использую cron.И я хочу использовать cron;Мне это нравится, это удобно, знакомо и т. Д.

Но cron, под 10.5.8 Leopard (требуется - проблемы с драйверами исключают 10.6), рвет тему сообщения с при каждом запуске, в основномзасорять то, что было бы полезным окном с бесполезным мусором.В crontab я устанавливаю переменные PATH, SHELL и HOME;все приложения, написанные на python, работают правильно и с ожидаемым R / W-доступом к оборудованию, каталогам и файлам, к которым они должны получить доступ;они хорошо запускают другие подзадачи Python;тем не менее, при запуске появляется жалоба cron, как будто что-то не так.

Возможно, что-то не так.Но, погуглив, я в основном нашел четыре вещи:

1) Эта проблема существовала долгое время - Apple не обращалась к ней

2) Если что-то не так с типичным запуском cron,кажется, никто не знает, что это такое

3) Это действительно распространено, и обычное предложение - "launchd", которое не будет работать

4) Единственное предложение, даже близко крешение состоит в том, чтобы установить уровень ведения журнала /etc/syslog.conf для консоли равным err вместо note ;но тогда в этом случае многие теряют преимущества консоли, и я очень неохотно работаю таким образом.

Я надеюсь, что здесь, в stackoverflow, найдется кто-то, кто действительно знает, что конкретносообщение об ошибке означает (в отличие от «launchd несчастен / обанкротился») или даже незаметно решило проблему самостоятельно.

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

Ответы [ 2 ]

1 голос
/ 03 мая 2011

Хорошо. Я сделал много поиска в Google, и есть несколько примечаний по этому вопросу. Во-первых, проблема существует годами. В сети огромное количество жалоб на это. Я нашел сообщение на форумах разработчиков Apple, где говорилось, что Apple знает об этом, это ошибка, и она будет исправлена ​​в будущем. Конечно, это замечание было опубликовано несколько лет назад (на самом деле три), и, очевидно, Apple не собирается это исправить. А пока у меня есть эти кровавые консольные сообщения, которые серьезно мешают мне. У меня есть настоящая работа, и мне нужно использовать консольный вывод в этой работе.

Так что я исправил это. :) Да, мои задания cron теперь работают тихо и правильно, как и всегда.

Теперь я хотел бы подчеркнуть, что это жестокое исправление и взлом, но оно довольно специфично для проблемы, я не думаю, что это может повредить чему-либо еще (если выполнено правильно) и служит МОИМ нуждам в совершенстве. Ваш пробег может отличаться, и если вы не технический специалист, прекратите читать сейчас и просто забудьте, что вы когда-либо видели этот пост. В самом деле. Остановись сейчас.

Итак, как вы можете заметить в приведенной выше публикации соответствующего куска исходного кода из launchd, который выкопал Грэм, есть вызов функции, который сообщает об этой конкретной ошибке. И в значительной степени именно эта конкретная ошибка.

Имеет четыре параметра, один из которых возвращается из вызова mach_error_string (). Единственным параметром, который является указателем (то есть вызываемая подпрограмма может каким-то образом вернуться к исходному параметру), является указатель строки и самоизменение строки статического формата ... нет. Это не та вещь, которую серьезно пили бы колаиды. Так что вызов ничего не делает с этими параметрами; их просто используют, чтобы сообщить об ошибке. Ясно, что нам не нужно делать этот звонок. Ах-ха. :)

Этот вызов mach_error_string оказывается уникальной подписью в версии 10.5.8 launchd. Это позволило мне точно найти код в исполняемом файле launchd. Оказавшись там, было довольно очевидно (для меня, во всяком случае), что происходит; есть соответствующее количество инструкций перемещения, затем вызов, затем цикл проверяется и либо выходит, либо перезапускается. Вот соответствующая часть разборки:

+193    0000fcd9  e87e050100              calll       0x0002025c                    _mach_error_string
+198    0000fcde  89442410                movl        %eax,0x10(%esp)
+202    0000fce2  8b462c                  movl        0x2c(%esi),%eax
+205    0000fce5  c7442408b8b90100        movl        $0x0001b9b8,0x08(%esp)
+213    0000fced  895c2404                movl        %ebx,0x04(%esp)
+217    0000fcf1  893c24                  movl        %edi,(%esp)
+220    0000fcf4  c1e808                  shrl        $0x08,%eax
+223    0000fcf7  25ff030000              andl        $0x000003ff,%eax
+228    0000fcfc  8944240c                movl        %eax,0x0c(%esp)
+232    0000fd00  e857afffff              calll       0x0000ac5c

Двоичная подпись вызова (опять же, я подчеркиваю, в версии 10.5.8 launchd на моей машине): E857AFFFFF. Во всем файле есть только один экземпляр этой двоичной строки.

Что нам нужно здесь сделать, это заменить это чем-то безвредным (в контексте) такой же длины. поблизости есть немедленная инструкция AND для eax; это сработает. Значение в eax больше не используется, поскольку цикл завершается после вызова. Двоичный файл для этой инструкции AND: 25FF030000. Даже если в худшем случае во время загрузки код был перекомпонован таким образом, чтобы (что было) адресом вызова был изменен, все, что могло бы произойти, - это то, что инструкция and имела бы другой шаблон AND. Так что, несмотря ни на что, это должно быть в порядке.

Итак, мы заменим E857AFFFFF на 25FF030000, и теперь код загружает эти параметры, и eax-регистр вообще не имеет смысла, и мы продолжаем жизнь. больше нет сообщений «Не удалось настроить специальный порт задачи Маха% u:% s». Когда-либо. И launchd продолжит работать так же, как и всегда, потому что все, что здесь было сделано, - это удалить вызов, чтобы записать сообщение об ошибке.

Теперь ... просто пара заключительных замечаний.

Во-первых, хотя взлом довольно специфичен, это не то, что я бы назвал хирургически точным; возможно, что где-то скрывается ситуация, которая законно будет вызывать это сообщение, или сообщение, отправленное с использованием этой строки формата и параметров с другим номером порта и / или строкой в ​​конце; и это не будет зарегистрировано, если это произойдет. Так что знайте об этом. Обработка ошибок, как она есть, не изменится, но ведение журнала ... теперь это невозможно.

Во-вторых, это взлом в классическом смысле; для меня это было и весело, и очень приятно, служа цели поднятия моей центральной цифры в общем направлении Apple, чтобы доставить мне неудобства с чем-то, что они могли бы легко исправить самостоятельно; для вас, тем не менее, если вы не знакомы с машинным кодом и двоичным кодом и / или не уверены, что вы можете сделать это совершенно правильно ... и вы не совсем готовы к тому, чтобы подключиться к вашей машине и заменить взломанный снова запустил оригинал ... или у вас нет 10.5.8 ... даже не пробуйте. Просто напишите Apple и скажите им, чтобы исправить их неработающий запуск.

Итак ... Apple дает нам ошибку; бросает мяч на его фиксацию; Я полностью потерял терпение и вырубил его с лица. И там у вас есть это. Pbbffft.

0 голосов
/ 27 апреля 2011

Давайте посмотрим на источник :).Поиск вашего сообщения об ошибке в http://www.opensource.apple.com/ находит это в launchd_core_logic.c :

kern_return_t
job_mig_post_fork_ping(job_t j, task_t child_task)
{
    struct machservice *ms;

    if (!launchd_assumes(j != NULL)) {
        return BOOTSTRAP_NO_MEMORY;
    }

    job_log(j, LOG_DEBUG, "Post fork ping.");

    job_setup_exception_port(j, child_task);

    SLIST_FOREACH(ms, &special_ports, special_port_sle) {
        if (j->per_user && (ms->special_port_num != TASK_ACCESS_PORT)) {
            /* The TASK_ACCESS_PORT funny business is to workaround 5325399. */
            continue;
        }

        errno = task_set_special_port(child_task, ms->special_port_num, ms->port);

        if (errno) {
            int desired_log_level = LOG_ERR;

            if (j->anonymous) {
                /* 5338127 */

                desired_log_level = LOG_WARNING;

                if (ms->special_port_num == TASK_SEATBELT_PORT) {
                    desired_log_level = LOG_DEBUG;
                }
            }

            job_log(j, desired_log_level, "Could not setup Mach task special port %u: %s", ms->special_port_num, mach_error_string(errno));
        }
    }

    job_assumes(j, launchd_mport_deallocate(child_task) == KERN_SUCCESS);

    return 0;
}

OK, поэтому здесь вы сможете найти имя специальногопорт № 9 и, следовательно, что launchd пытается сделать, когда он отправляет сообщение.Похоже, это происходит во время переноса портов маха из запущенного в дочерний процесс, но я не знаю, что он там делает.Возможно, вы захотите отправить по электронной почте devbugs@apple.com и спросить их, что такое радары 5325399 и 5338127, поскольку они имеют отношение к реализации этой функции.

...