java — сигнал 10 (SIGBUS) в библиотеке c ++ при запуске приложения в качестве демона launchd

У меня есть Java-приложение, которое запускает вспомогательное приложение c ++ для извлечения информации из базы данных (длинный рассказ о старых 32-битных драйверах). Когда я запускаю приложение вручную, все работает отлично, приложение c ++ запускается и приложение Java потребляет вывод. Но когда java-приложение запускается как демон launchd, вспомогательное приложение c ++ возвращается со значением выхода 138, что, я уверен, является ошибкой шины 10.

После некоторой довольно болезненной отладки я смог определить, что сигнал происходит внутри самого драйвера ODBC. Поскольку у меня нет доступа к источнику для драйвера ODBC, мои возможности отладки ограничены.

У меня такой вопрос: я что-то упускаю в моей настройке launchd plist, которая может помочь объяснить, что происходит, или происходит какая-то песочница, которая может вызвать мою проблему?

Я новичок в OSX, поэтому у меня очень мало опыта в запуске.

Вот моя текущая настройка plist.

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.my.package.name</string>
<key>ProgramArguments</key>
<array>
<string>java</string>
<string>-cp</string>
<string> my classpath</string>
<string> my main class</string>
</array>
<key>KeepAlive</key>
<true/>
<key>WorkingDirectory</key>
<string>my working directory</string>
</dict>
</plist>

Редактировать:
Мне удалось получить файл сбоя. Вот ошибка и трассировка стека. DSN действительно настроен правильно в INI-файле, но я продолжу копать.

Я смог получить файл аварийного завершения для этого, и вот ошибка и трассировка стека.

Exception Type:  EXC_BAD_ACCESS (SIGBUS)
Exception Codes: KERN_PROTECTION_FAILURE at 0x0000000000000000

VM Regions Near 0:
--> __PAGEZERO             0000000000000000-0000000000001000 [    4K] ---/--- SM=NUL  /Users/*
VM_ALLOCATE            0000000000001000-00000000000f7000 [  984K] ---/--- SM=NUL

Thread 0 Crashed:: Dispatch queue: com.apple.main-thread

0   libsystem_c.dylib               0x905c47f0 strlen + 16
1   com.4D.odbcdriver.v13           0x00308c14 _LoadOdbcIni() + 257
2   com.4D.odbcdriver.v13           0x00309546 _GetStringFromSystemDSN(char const*, char const*, char*, int) + 60
3   com.4D.odbcdriver.v13           0x0030967e SQLGetPrivateProfileStringW + 99
4   com.4D.odbcdriver.v13           0x002f0ec9 CHConnection::CreateStringFromDSN(wchar_t const*, wchar_t const*, wchar_t const*) + 225
5   com.4D.odbcdriver.v13           0x00307e4a internalSQLDriverConnectW(CHConnection*, void*, wchar_t*, short, wchar_t*, short, short*, unsigned short) + 311
6   com.4D.odbcdriver.v13           0x002fcafb SQLDriverConnectW + 129
7   org.iodbc.core                  0x0025802d SQLDriverConnect_Internal + 2381
8   org.iodbc.core                  0x00259373 SQLDriverConnect + 323

1

Решение

По трассировке стека (когда отформатировано для разборчивости ☺) довольно очевидно, что здесь происходит.

Это очевидно Драйвер 4D ODBC. Это звонит strlen(), Он ударил NULL указатель. strlen() был вызван внутренней библиотекой _LoadOdbcIni() функция.

Мое обоснованное предположение заключается в том, что драйвер ODBC использует .INI файл, и что он получает местоположение этого файла из переменной среды. Эта переменная окружения установлена ​​в конфигурации вашего рабочего стола / в профиле оболочки / в любом другом месте. Но это не в вашем списке и не установлено, когда launchd призывает вашего демона.

Код в драйвере вызывает std::getenv() получить переменную среды, которая возвращает NULL, Библиотека не была написана, чтобы ожидать, что переменная среды будет отсутствовать. Это просто вызов strlen() на что NULL указатель без проверки на это. И — взрыв! — SIGBUS а также KERN_PROTECTION_FAILURE при попытке доступа к адресу 0x0000000000000000,

Узнайте из документа 4D, что бы это ни было, или из службы технической поддержки 4D, или из какого-либо другого источника, какие переменные среды необходимы драйверу для этого .INI файл (и все остальное); и установите это в своем списке. man launchd.plist кстати, как это сделать, кстати.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]