Skip to content

Commit 33d1ffa

Browse files
Johannes Carlssonjredestig
authored andcommitted
Fix shutdown sequence to avoid SIGSEGV when running am command
When the app_process is shutting down the main thread will close the binder fd while pool threads are executing an ioctl (in IPCThreadState::stopProcess called by AppRuntime::onStarted in app_main.c). The binder driver will then return all pending calls in ioctl without any error and with a command. One of the threads gets a BR_SPAWN_LOOPER which will create a new thread (the other thread gets a BR_NOOP). This new thread then calls vm->AttachCurrentThread. Usually this results in a log entry with "AndroidRuntime: NOTE: attach of thread 'Binder Thread zsol#3' failed", but sometimes it also causes a SIGSEGV. This depends on the timing between the new thread an the main thread that calls DestroyJavaVM (in AndroidRuntime::start). If IPCThreadState.cpp is compiled with "#define LOG_NDEBUG 0" the pool thread will loop and hit the ALOG_ASSERT(mProcess->mDriverFD >= 0) in IPCThreadState::talkWithDriver. Crashes like this has been seen when running the am command and other commands that use the app_process. This fix makes sure that any command that is received when the driver fd is closed are ignored and IPCThreadState::talkWithDriver instead returns an error which will cause the pool thread to exit and detach itself from the vm. A check to avoid calling ioctl to a fd with -1 was also added in IPCThreadState::threadDestructor. Another solution might be to change the binder driver so that it returns an error when the fd is closed (or atleast not a BR_SPAWN_LOOPER command). It might also be possible to call exit(0) which is done when System.exit(0) is called from java. Change-Id: I3d1f0ff64896c44be2a5994b3a90f7a06d27f429
1 parent 0748a56 commit 33d1ffa

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

libs/binder/IPCThreadState.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -752,7 +752,9 @@ status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
752752

753753
status_t IPCThreadState::talkWithDriver(bool doReceive)
754754
{
755-
ALOG_ASSERT(mProcess->mDriverFD >= 0, "Binder driver is not opened");
755+
if (mProcess->mDriverFD <= 0) {
756+
return -EBADF;
757+
}
756758

757759
binder_write_read bwr;
758760

@@ -808,6 +810,9 @@ status_t IPCThreadState::talkWithDriver(bool doReceive)
808810
#else
809811
err = INVALID_OPERATION;
810812
#endif
813+
if (mProcess->mDriverFD <= 0) {
814+
err = -EBADF;
815+
}
811816
IF_LOG_COMMANDS() {
812817
alog << "Finished read/write, write size = " << mOut.dataSize() << endl;
813818
}
@@ -1099,7 +1104,9 @@ void IPCThreadState::threadDestructor(void *st)
10991104
if (self) {
11001105
self->flushCommands();
11011106
#if defined(HAVE_ANDROID_OS)
1102-
ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0);
1107+
if (self->mProcess->mDriverFD > 0) {
1108+
ioctl(self->mProcess->mDriverFD, BINDER_THREAD_EXIT, 0);
1109+
}
11031110
#endif
11041111
delete self;
11051112
}

0 commit comments

Comments
 (0)