IT技术博客大学习 共学习 共进步
全部 移动开发 后端 数据库 AI 算法 安全 DevOps 前端 设计 开发者

iOS安全–不同平台的崩溃收集

Coder 2016-03-01 23:52:19 累计浏览 2,054 次
本机暂存

发布的app难免会出现一些奇葩的bug,为了能够实时跟踪app的崩溃,需要接管系统的异常捕获接口,自己来收集保存崩溃现场信息。

下面简单说一下几个平台的异常崩溃捕获。

1.iOS

1.1 Exception

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-(BOOL)install{
if(NSGetUncaughtExceptionHandler() != custom_exceptionHandler)
oldhandler = NSGetUncaughtExceptionHandler();

if(self->_handlerEnable){
NSSetUncaughtExceptionHandler(&custom_exceptionHandler);
}else{
DDLogWarning(@"NSEXception handler disable");
}
return YES;
}

-(BOOL)uninstall{
NSSetUncaughtExceptionHandler(oldhandler);
return YES;
}

1.2 Signal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
-(BOOL)install{
if(installed){
DDLogError(@"signal handler has been installed");
return NO;
}

custom_crash_stk.ss_size = MAX(MINSIGSTKSZ, 64*1024);
custom_crash_stk.ss_sp = malloc(custom_crash_stk.ss_size);
custom_crash_stk.ss_flags = 0;

if(custom_crash_stk.ss_sp == NULL){
return NO;
}

//替换信号处理函数栈,避免栈已经耗尽,导致进程退出
if(sigaltstack(&custom_crash_stk, 0) < 0)
return NO;

if(!sa_preHandlers){
sa_preHandlers = (struct sigaction*)malloc(sizeof(struct sigaction) * monitored_signals_count);
memset(sa_preHandlers, 0, sizeof(struct sigaction) * monitored_signals_count);
}

struct sigaction sa;
memset(&sa, 0, sizeof(sa));
sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = &custom_signalHandler;

for (int i = 0; i < monitored_signals_count; i++) {
if(sigaction(monitored_signals[i], &sa, (struct sigaction*)(sa_preHandlers+i)) != 0){
DDLogError(@"install signalHandler failed, uninstall it!");
[self uninstall];
return NO;
}
}

installed = 1;

return YES;
}

-(BOOL)uninstall{
if(installed){
if(custom_crash_stk.ss_sp){
free(custom_crash_stk.ss_sp);
custom_crash_stk.ss_sp = nil;
}

for (int i = 0; i < monitored_signals_count; i++) {
if(sigaction(monitored_signals[i], (struct sigaction*)(sa_preHandlers+i), 0) != 0){
return NO;
}
}

if(sa_preHandlers)
free(sa_preHandlers);

installed = 0;

return YES;
}else{
DDLogError(@"signalHandler already uninstalled!");
return NO;
}
}

2.Cocos

2.1 Cocos-Lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
local function handleLuaException(msg)
if msg==nil then return end

local targetPlatform = cc.Application:getInstance():getTargetPlatform()
local supportObjectCBridge  = false
if (cc.PLATFORM_OS_IPHONE == targetPlatform) or (cc.PLATFORM_OS_IPAD == targetPlatform) or (cc.PLATFORM_OS_MAC == targetPlatform)  then
supportObjectCBridge = true
end

local supportJavaBridge = false
if (cc.PLATFORM_OS_ANDROID == targetPlatform) then
supportJavaBridge = true
end

if (supportJavaBridge == true) then
//...
elseif (supportObjectCBridge == true) then
//...
end
end

function __G__TRACKBACK__(msg)
handleLuaException(msg)
return msg
end

2.2 Cocos-JS

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//注册异常处理回调函数
void JSExceptionHandler::registerJSExceptionHandler(JSContext *cx) {
JS_SetErrorReporter(cx, JSExceptionHandler::reportError);
}

void JSExceptionHandler::reportError(JSContext *cx, const char *message, JSErrorReport *report)
{
const char* format = "%s:%u:%s\n";
const char* fileName = report->filename ? report->filename : "no filename";

int bufLen = strlen(format) + strlen(fileName) + strlen(message) + 16;
char* traceback = (char*)malloc(bufLen);
memset(traceback, 0, bufLen);
sprintf(traceback, format, fileName, (unsigned int) report->lineno, message);

//....

free(traceback);
};

3.U3D

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//注册未处理异常回调
System.AppDomain.CurrentDomain.UnhandledException += _OnUnhandledExceptionHandler;

//注册日志回调
Application.RegisterLogCallback(_OnLogCallbackHandler);

static private void _OnLogCallbackHandler(string name, string stack, LogType type)
{

//…
}

private static void _OnUnhandledExceptionHandler(object sender, System.UnhandledExceptionEventArgs args)
{
if (args.ExceptionObject.GetType() == typeof(System.Exception))
{
  //…      

}
}

同分类推荐文章

  1. 「置顶」我做了什么 (2026-05-05 12:13:28)
  2. 万字长文推演:手机不再从 App 开始,Agent OS 如何接管任务入口 (2026-04-28 14:57:22)
  3. Android Perfetto 系列 10 - Binder 调度与锁竞争 (2025-11-16 15:33:30)

查看更多 移动开发 文章 →

建议继续学习

  1. PHP的异常原理与实例说明 Fatal error: Uncaught exception (累计阅读 9,763)
  2. App的成本 (累计阅读 7,584)
  3. 是返回错误码,还是抛出异常?说说我的选择 (累计阅读 7,546)
  4. iPhone下的libcurl with SSL for iOS (累计阅读 6,350)
  5. iOS的定位原理揭秘 (累计阅读 5,946)
  6. iOS内存暴增问题追查与使用陷阱 (累计阅读 5,838)
  7. IOS APP设计流程 (累计阅读 5,085)
  8. 在Visual Studio中使用MonoTouch开发iOS应用程序(上):环境配置 (累计阅读 5,076)
  9. iOS push服务 (累计阅读 4,943)
  10. 有关思维,有关Ipad一个Bug的故事 (累计阅读 4,770)