I'm implementing a HAL component for which I'm creating a test. The test is actually about creating a mock of the HAL callbacks in a different process, and registering itself to the HAL. In other words, I'm mocking the client of the HAL, then simulating a client crash causing a transaction failure to test the HAL ability to handle errors. The problem is, trying to use Binder IPC inside a fork causes a segfault. Reading this question and from the documentation I understood that the HwBinder thread starts automatically by linking to the libbiner.
Given that fork()
does not copy the running threads of the parent, this means that the forked process will not find the helper HwBinder thread, or it does assume it exists and try to use it anyway?
This creates a chain of errors ending up by having a SEGV_MAPERR.
My question is, is there anyway to re-initiate the HwBinder thread inside my forked child without having to use exec
?
Here is my code:
pid_t pid = fork();
if (pid == 0) {
using namespace ::android::hardware;
using namespace testing;
/**
* Crash happens here
*/
android::sp<IMyHal> iMyHal = IMyHal::getService();
IMyHal->deregisterMyHalCallback();
sp<MockIMyHalCallback> callbackMock(new MockIMyHalCallback());
iMyHal->deregisterMyHalCallback(callbackMock);
Status hidlStatus;
hidlStatus.setException(Status::EX_TRANSACTION_FAILED, "Transaction Failed");
EXPECT_CALL(*callbackMock, testFunction(Eq("1"), _))
.WillOnce(DoAll(testing::Return(ByMove(android::hardware::Return<void>(hidlStatus)))))
.Times(Exactly(1));
} else if (pid > 0) {
/**
* This will trigger iMyHal to call callbackMock.testFunction();
*/
mProxy->callTestFunction("1", 2);
}
This results in this error:
2020-10-30 19:18:31.440 18917-18917/? A/libc: Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xef400000 in tid 18917 (vendor.xxx.remo), pid 18917 (vendor.xxx.remo)
Do you intend to test your HAL or cross-process HwBinder implementation? In the first case, you may not need to create a whole separate process to test your HAL.
The usual way it's done is: