{ "id": "102436", "key": "TIMOB-11217", "fields": { "issuetype": { "id": "1", "description": "A problem which impairs or prevents the functions of the product.", "name": "Bug", "subtask": false }, "project": { "id": "10153", "key": "TIMOB", "name": "Titanium SDK/CLI", "projectCategory": { "id": "10100", "description": "Titanium and related SDKs used in application development", "name": "Client" } }, "fixVersions": [], "resolution": { "id": "6", "description": "", "name": "Hold" }, "resolutiondate": "2012-10-16T02:38:13.000+0000", "created": "2012-09-30T05:53:36.000+0000", "priority": { "name": "High", "id": "2" }, "labels": [ "core" ], "versions": [ { "id": "13505", "description": "Release 3.0.0", "name": "Release 3.0.0", "archived": true, "released": true, "releaseDate": "2012-12-14" } ], "issuelinks": [], "assignee": { "name": "mstepanov", "key": "mstepanov", "displayName": "Max Stepanov", "active": true, "timeZone": "America/Los_Angeles" }, "updated": "2017-03-21T21:13:28.000+0000", "status": { "description": "The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.", "name": "Closed", "id": "6", "statusCategory": { "id": 3, "key": "done", "colorName": "green", "name": "Done" } }, "components": [ { "id": "10206", "name": "iOS", "description": "iOS Platform" } ], "description": "it looks like not all types of errors are handled in TiExceptionHandler\r\n\r\nif you add the following:\r\n\r\n{code}\r\nabort()\r\n{code}\r\n\r\nin a module method, the app will crash.\r\n\r\nsee http://cocoawithlove.com/2010/05/handling-unhandled-exceptions-and.html for a good example on how to handle signals as well as normal cocoa exceptions (in addition to script error and NSExceptionHandler). the signal handling code must be added to TiExceptionHandler.m\r\n\r\n", "attachment": [], "flagged": false, "summary": "iOS: Signals are not being handled by the TiExceptionHandler", "creator": { "name": "jhaynie", "key": "jhaynie", "displayName": "Jeff Haynie", "active": false, "timeZone": "America/Los_Angeles" }, "subtasks": [], "reporter": { "name": "jhaynie", "key": "jhaynie", "displayName": "Jeff Haynie", "active": false, "timeZone": "America/Los_Angeles" }, "environment": "3.0.0.b66de42", "comment": { "comments": [ { "id": "221522", "author": { "name": "jhaynie", "key": "jhaynie", "displayName": "Jeff Haynie", "active": false, "timeZone": "America/Los_Angeles" }, "body": "submitted pull request at https://github.com/appcelerator/titanium_mobile/pull/3086", "updateAuthor": { "name": "jhaynie", "key": "jhaynie", "displayName": "Jeff Haynie", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2012-09-30T07:42:51.000+0000", "updated": "2012-09-30T07:42:51.000+0000" }, { "id": "223739", "author": { "name": "mstepanov", "key": "mstepanov", "displayName": "Max Stepanov", "active": true, "timeZone": "America/Los_Angeles" }, "body": "Going to quote Mike Ash from Friday Q&A 2011-04-01: Signal Handling:\r\n{quote}\r\nThe problem is that signals are delivered asynchronously, and the function registered here is also invoked asynchronously. Code always has to run on a thread somewhere. Depending on how the signal is generated, the handler is either run on the thread that the signal is associated with (for example, a SIGSEGV handler will run on the thread that segfaulted) or it will run on an arbitrary thread in the process. The problem is that it's essentially an interrupt in userland, and whatever code was running when it came in will be paused until the handler is done.\r\n\r\nAs anyone who was around in the classic Mac days knows, writing code that runs in an interrupt is hard. The problem is reentrancy. Many people confuse reentrancy with thread safety, but they are not the same concept, although they are somewhat similar.\r\n\r\nThread safety means that a particular piece of code can run on multiple threads at the same time safely. Thread safety is most commonly accomplished by using locks. A call acquires a lock, does work, releases the lock. A second thread that comes along in the middle will block until the first thread is done.\r\n\r\nIf code is reentrant that means that a particular piece of code can run multiple times on the same thread safely. This is different and considerably harder.\r\n\r\nWhat if you take the thread safety approach of locking and apply it to reentrancy? The first call acquires the lock. While it's active, the code is called again. It tries to acquire the lock, but the lock is already taken, so it blocks. However, the first call can't run until the second call is done. The second call can't run until the first call is done. The result is a frozen program.\r\n\r\nWriting reentrant code is hard, and as a result very few system functions are reentrant. Because a signal handler functions as an interrupt, it can only call reentrant code. You can't call something as simple as printf safely, because printf could take a lock, and if there's already an active call to printf on the thread where the handler runs, you'll deadlock.\r\n\r\nThe sigaction man page gives a list of functions you are allowed to call from a signal handler. It's pretty limited.\r\n\r\nThe complete list is: _exit(), access(), alarm(), cfgetispeed(), cfgetospeed(), cfsetispeed(), cfsetospeed(), chdir(), chmod(), chown(), close(), creat(), dup(), dup2(), execle(), execve(), fcntl(), fork(), fpathconf(), fstat(), fsync(), getegid(), geteuid(), getgid(), getgroups(), getpgrp(), getpid(), getppid(), getuid(), kill(), link(), lseek(), mkdir(), mkfifo(), open(), pathconf(), pause(), pipe(), raise(), read(), rename(), rmdir(), setgid(), setpgid(), setsid(), setuid(), sigaction(), sigaddset(), sigdelset(), sigemptyset(), sigfillset(), sigismember(), signal(), sigpending(), sigprocmask(), sigsuspend(), sleep(), stat(), sysconf(), tcdrain(), tcflow(), tcflush(), tcgetattr(), tcgetpgrp(), tcsendbreak(), tcsetattr(), tcsetpgrp(), time(), times(), umask(), uname(), unlink(), utime(), wait(), waitpid(), write(), aio_error(), sigpause(), aio_return(), aio_suspend(), sem_post(), sigset(), strcpy(), strcat(), strncpy(), strncat(), strlcpy(), strlcat().\r\n\r\n\r\nFinally, the list ends with this amusing note: \"...and perhaps some others.\" \"Perhaps\" is not a nice word to run into in this sort of documentation.\r\n\r\n*You can call your own reentrant code, but you probably don't have any, because it's hard to write, it can't call any system functions except from the above list, and you never had any reason to write it before. For the Objective-C types, note that objc_msgSend is not reentrant, so you cannot use any Objective-C from a signal handler.*\r\n\r\n{color:red}*There is very little that you can do safely. There is so little that I'm not even going to discuss how to get anything done, because it's so impractical to do so, and instead will simply tell you to avoid using signal handlers unless you really know what you're doing and you enjoy pain.*\r\n{color}\r\n{quote}\r\n\r\nAs well, from the source mentioned in the description:\r\n{quote}\r\n*Limitations*\r\n*The signal handler is not re-entrant*\r\nRemember from the paragraph at the beginning:\r\n\r\nThe code in this post performs signal handling in non re-entrant way — this is not a reliable thing to do and is only done because proper re-entrant coding is brutally difficult and the assumption is that your program has already fatally crashed so we're not too worried. If multiple signals are caught, this code probably won't help at all.\r\nIf you want to learn how to write signal handlers for non-crash related signals or learn how to write proper re-entrant signal handling, I'm afraid you'll need to look elsewhere — there's not enough space here for me to show you and it's really hard. Ignoring this constraint here is okay for debug code only where we assume we're only going to get 1 signal.\r\n\r\n{quote}\r\n\r\n\r\nThe best what we could do is to integrate PLCrashReporter framework to generate crash report during signal handler, but no details could be displayed to users. The crash log could be potentially sent to a server on next app launch. This will effectively match what iOS does by default with crashing apps. ", "updateAuthor": { "name": "mstepanov", "key": "mstepanov", "displayName": "Max Stepanov", "active": true, "timeZone": "America/Los_Angeles" }, "created": "2012-10-16T05:58:58.000+0000", "updated": "2012-10-16T06:08:58.000+0000" }, { "id": "414423", "author": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "body": "Closing ticket due to the time that has passed since this was filed.", "updateAuthor": { "name": "lmorris", "key": "lmorris", "displayName": "Lee Morris", "active": false, "timeZone": "America/Los_Angeles" }, "created": "2017-03-21T21:13:28.000+0000", "updated": "2017-03-21T21:13:28.000+0000" } ], "maxResults": 3, "total": 3, "startAt": 0 } } }