Objective C 运行 通过 OSX Cron 命令失败
Objective C Command Failing When Run Through OSX Cron
我编写了一个独立的 Objective C 命令应用程序。如果我通过 LaunchDaemon 运行 它,当 ObjC 客户端应用程序通过 DistriutedObjects 通信连接时它 运行 就好了。如果我在命令行 运行 它,它 运行 就好了。如果我 运行 它在被 Bash 脚本调用时,它 运行 就好了。但是,我尝试通过 root 用户的 crontab 运行 以各种方式执行此操作,它会生成有关指针分配的崩溃报告:
Apr 14 05:27:00 volomike cron[72531]: cron(72531,0x7fff7d2fa000) malloc: *** error for object 0x7fb9c8400213: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Apr 14 05:27:00 volomike diagnosticd[70689]: error evaluating process info - pid: 72531, puniqueid: 72531
Apr 14 05:27:00 volomike com.apple.xpc.launchd[1] (com.vix.cron[72531]): Service exited due to signal: Abort trap: 6
Apr 14 05:27:00 volomike com.apple.xpc.launchd[1] (com.apple.ReportCrash.Root[72550]): Endpoint has been activated through legacy launch(3) APIs. Please switch to XPC or bootstrap_check_in(): com.apple.ReportCrash.DirectoryService
Apr 14 05:27:00 volomike ReportCrash[72550]: Saved crash report for cron[72531] version 39 to /Library/Logs/DiagnosticReports/cron_2016-04-14-052700_volomike.crash
该崩溃报告的重要部分如下:
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Application Specific Information:
abort() called
*** error for object 0x7fb9c8400213: pointer being freed was not allocated
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x00007fff9490ff06 __pthread_kill + 10
1 libsystem_pthread.dylib 0x00007fff9c45e4ec pthread_kill + 90
2 libsystem_c.dylib 0x00007fff9345b6e7 abort + 129
3 libsystem_malloc.dylib 0x00007fff9c02f041 free + 425
4 cron 0x000000010367aa41 0x103677000 + 14913
5 cron 0x000000010367a7e4 0x103677000 + 14308
6 cron 0x0000000103679572 0x103677000 + 9586
7 cron 0x000000010367925a 0x103677000 + 8794
8 cron 0x000000010367885e 0x103677000 + 6238
9 libdyld.dylib 0x00007fff949835ad start + 1
以各种方式,我已经用这些不同的 cron 行完成了,但是当尝试调用命令时它们立即崩溃,甚至当我有 NSLog() 写东西到 /var/log/system.log 时从 main 的开始到应用程序的结束,没有任何东西被写入——就像当 cron 试图调用我的命令时,它立即死掉,并出现关于指针分配的崩溃报告。
41 5 * * * /bin/bash '/Applications/My App.app/Contents/Resources/mytoolcommand.sh' /q /sched
41 5 * * * /bin/bash '/Applications/My App.app/Contents/Resources/mytoolcommand.sh' /q /sched &
41 5 * * * '/Applications/My App.app/Contents/Resources/mytoolcommand' /q /sched
41 5 * * * '/Applications/My App.app/Contents/Resources/mytoolcommand' /q /sched &
再次注意,如果我 '/Applications/My App.app/Contents/Resources/mytoolcommand.sh' /q /sched
,它 运行 就好了,/bin/bash '/Applications/My App.app/Contents/Resources/mytoolcommand.sh' /q /sched
,'/Applications/My App.app/Contents/Resources/mytoolcommand' /q /sched
我什至做了一个变体,其中 cron 调用我的 mytoolcommand.sh 脚本并将 Hello World 简单地写到 /tmp/out.txt,它 运行 就好了。所以,我知道我的 crontab 正在工作。
你能帮我弄清楚我做错了什么吗?一些疑似可能的问题:
也许 OSX El Capitan 出于某种原因关闭了我的应用程序,例如未正确签名。 (我现在正在调试。我以前从未遇到过签名问题,除非它处理 .app 文件夹。此外,我可以 运行 从命令行中正常运行而没有签名警告。)
我立即从 main() 加载了调试消息。他们应该写入 /var/log/system.log,但他们没有。这告诉我应用程序在被 cron 调用时立即崩溃。那么,是否需要将一些特殊的东西加载到我的应用程序的库中,以便在 cron 下调用时正确 运行?
发展
我怀疑 El Capitan Gatekeeper 可能是原因。因此,我在 main.mm 文件中创建了一个简单的 Objective C 控制台应用程序并进行了编译。
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *sTest = @"Hello World";
[sTest writeToFile:@"/tmp/test.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil];
}
return 0;
}
Cron 似乎 运行 这很好,所以看起来不像是 Gatekeeper 问题。
我让问题消失了,但只是短暂地消失了。我在 b运行d 新项目中重新编译了该项目,复制了源代码和设置。然后,我 运行 通过 cron 命令执行了大约 4 次,没有任何问题。然而,当我运行它第五次时,它再次失败并继续失败。
所以,我想我必须弄清楚如何将其转换为 LaunchAgent。
答案是你不知道。在 OSX 上,您不再为正在编码的应用程序使用 cron。相反,切换到 LaunchAgent。当然,Apple 保留它是为了 POSIX 支持,因此可能会保留很长时间,但即使是他们的网站也鼓励人们不再使用 cron 进行应用程序编码。
"Note: Although it is still supported, cron is not a recommended
solution. It has been deprecated in favor of launchd."
不幸的是,LaunchAgents 还不支持(至少在 10.11.4 中)cron-style 语法。 (是的,我已经为您向 Apple 提交了该建议。)因此,没有使用破折号、逗号或反斜杠。相反,它只支持一个整数和多个块来创建每个时间帧。如果这还不够合适,那么至少设置最短的时间范围,然后在您要启动的任何内容中执行其余代码,例如,如果您只想在第一个星期一 运行当月,LaunchDaemon 在前 7 天启动,但如果不是当月的第一个星期一,您的应用程序会关闭。
我编写了一个独立的 Objective C 命令应用程序。如果我通过 LaunchDaemon 运行 它,当 ObjC 客户端应用程序通过 DistriutedObjects 通信连接时它 运行 就好了。如果我在命令行 运行 它,它 运行 就好了。如果我 运行 它在被 Bash 脚本调用时,它 运行 就好了。但是,我尝试通过 root 用户的 crontab 运行 以各种方式执行此操作,它会生成有关指针分配的崩溃报告:
Apr 14 05:27:00 volomike cron[72531]: cron(72531,0x7fff7d2fa000) malloc: *** error for object 0x7fb9c8400213: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Apr 14 05:27:00 volomike diagnosticd[70689]: error evaluating process info - pid: 72531, puniqueid: 72531
Apr 14 05:27:00 volomike com.apple.xpc.launchd[1] (com.vix.cron[72531]): Service exited due to signal: Abort trap: 6
Apr 14 05:27:00 volomike com.apple.xpc.launchd[1] (com.apple.ReportCrash.Root[72550]): Endpoint has been activated through legacy launch(3) APIs. Please switch to XPC or bootstrap_check_in(): com.apple.ReportCrash.DirectoryService
Apr 14 05:27:00 volomike ReportCrash[72550]: Saved crash report for cron[72531] version 39 to /Library/Logs/DiagnosticReports/cron_2016-04-14-052700_volomike.crash
该崩溃报告的重要部分如下:
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Application Specific Information:
abort() called
*** error for object 0x7fb9c8400213: pointer being freed was not allocated
Thread 0 Crashed:: Dispatch queue: com.apple.main-thread
0 libsystem_kernel.dylib 0x00007fff9490ff06 __pthread_kill + 10
1 libsystem_pthread.dylib 0x00007fff9c45e4ec pthread_kill + 90
2 libsystem_c.dylib 0x00007fff9345b6e7 abort + 129
3 libsystem_malloc.dylib 0x00007fff9c02f041 free + 425
4 cron 0x000000010367aa41 0x103677000 + 14913
5 cron 0x000000010367a7e4 0x103677000 + 14308
6 cron 0x0000000103679572 0x103677000 + 9586
7 cron 0x000000010367925a 0x103677000 + 8794
8 cron 0x000000010367885e 0x103677000 + 6238
9 libdyld.dylib 0x00007fff949835ad start + 1
以各种方式,我已经用这些不同的 cron 行完成了,但是当尝试调用命令时它们立即崩溃,甚至当我有 NSLog() 写东西到 /var/log/system.log 时从 main 的开始到应用程序的结束,没有任何东西被写入——就像当 cron 试图调用我的命令时,它立即死掉,并出现关于指针分配的崩溃报告。
41 5 * * * /bin/bash '/Applications/My App.app/Contents/Resources/mytoolcommand.sh' /q /sched
41 5 * * * /bin/bash '/Applications/My App.app/Contents/Resources/mytoolcommand.sh' /q /sched &
41 5 * * * '/Applications/My App.app/Contents/Resources/mytoolcommand' /q /sched
41 5 * * * '/Applications/My App.app/Contents/Resources/mytoolcommand' /q /sched &
再次注意,如果我 '/Applications/My App.app/Contents/Resources/mytoolcommand.sh' /q /sched
,它 运行 就好了,/bin/bash '/Applications/My App.app/Contents/Resources/mytoolcommand.sh' /q /sched
,'/Applications/My App.app/Contents/Resources/mytoolcommand' /q /sched
我什至做了一个变体,其中 cron 调用我的 mytoolcommand.sh 脚本并将 Hello World 简单地写到 /tmp/out.txt,它 运行 就好了。所以,我知道我的 crontab 正在工作。
你能帮我弄清楚我做错了什么吗?一些疑似可能的问题:
也许 OSX El Capitan 出于某种原因关闭了我的应用程序,例如未正确签名。 (我现在正在调试。我以前从未遇到过签名问题,除非它处理 .app 文件夹。此外,我可以 运行 从命令行中正常运行而没有签名警告。)
我立即从 main() 加载了调试消息。他们应该写入 /var/log/system.log,但他们没有。这告诉我应用程序在被 cron 调用时立即崩溃。那么,是否需要将一些特殊的东西加载到我的应用程序的库中,以便在 cron 下调用时正确 运行?
发展
我怀疑 El Capitan Gatekeeper 可能是原因。因此,我在 main.mm 文件中创建了一个简单的 Objective C 控制台应用程序并进行了编译。
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
@autoreleasepool {
NSString *sTest = @"Hello World";
[sTest writeToFile:@"/tmp/test.txt" atomically:YES encoding:NSUTF8StringEncoding error:nil];
}
return 0;
}
Cron 似乎 运行 这很好,所以看起来不像是 Gatekeeper 问题。
我让问题消失了,但只是短暂地消失了。我在 b运行d 新项目中重新编译了该项目,复制了源代码和设置。然后,我 运行 通过 cron 命令执行了大约 4 次,没有任何问题。然而,当我运行它第五次时,它再次失败并继续失败。
所以,我想我必须弄清楚如何将其转换为 LaunchAgent。
答案是你不知道。在 OSX 上,您不再为正在编码的应用程序使用 cron。相反,切换到 LaunchAgent。当然,Apple 保留它是为了 POSIX 支持,因此可能会保留很长时间,但即使是他们的网站也鼓励人们不再使用 cron 进行应用程序编码。
"Note: Although it is still supported, cron is not a recommended solution. It has been deprecated in favor of launchd."
不幸的是,LaunchAgents 还不支持(至少在 10.11.4 中)cron-style 语法。 (是的,我已经为您向 Apple 提交了该建议。)因此,没有使用破折号、逗号或反斜杠。相反,它只支持一个整数和多个块来创建每个时间帧。如果这还不够合适,那么至少设置最短的时间范围,然后在您要启动的任何内容中执行其余代码,例如,如果您只想在第一个星期一 运行当月,LaunchDaemon 在前 7 天启动,但如果不是当月的第一个星期一,您的应用程序会关闭。