@@ -172,6 +172,8 @@ class CrasherTest : public ::testing::Test {
172
172
void StartCrasher (const std::string& crash_type);
173
173
void FinishCrasher ();
174
174
void AssertDeath (int signo);
175
+
176
+ static void Trap (void * ptr);
175
177
};
176
178
177
179
CrasherTest::CrasherTest () {
@@ -334,6 +336,48 @@ TEST_F(CrasherTest, tagged_fault_addr) {
334
336
R"( signal 11 \(SIGSEGV\), code 1 \(SEGV_MAPERR\), fault addr (0x100000000000dead|0xdead))" );
335
337
}
336
338
339
+ // Marked as weak to prevent the compiler from removing the malloc in the caller. In theory, the
340
+ // compiler could still clobber the argument register before trapping, but that's unlikely.
341
+ __attribute__ ((weak)) void CrasherTest::Trap(void * ptr ATTRIBUTE_UNUSED) {
342
+ __builtin_trap ();
343
+ }
344
+
345
+ TEST_F (CrasherTest, heap_addr_in_register) {
346
+ #if defined(__i386__)
347
+ GTEST_SKIP () << " architecture does not pass arguments in registers" ;
348
+ #endif
349
+ int intercept_result;
350
+ unique_fd output_fd;
351
+ StartProcess ([]() {
352
+ // Crash with a heap pointer in the first argument register.
353
+ Trap (malloc (1 ));
354
+ });
355
+
356
+ StartIntercept (&output_fd);
357
+ FinishCrasher ();
358
+ int status;
359
+ ASSERT_EQ (crasher_pid, TIMEOUT (30 , waitpid (crasher_pid, &status, 0 )));
360
+ ASSERT_TRUE (WIFSIGNALED (status)) << " crasher didn't terminate via a signal" ;
361
+ // Don't test the signal number because different architectures use different signals for
362
+ // __builtin_trap().
363
+ FinishIntercept (&intercept_result);
364
+
365
+ ASSERT_EQ (1 , intercept_result) << " tombstoned reported failure" ;
366
+
367
+ std::string result;
368
+ ConsumeFd (std::move (output_fd), &result);
369
+
370
+ #if defined(__aarch64__)
371
+ ASSERT_MATCH (result, " memory near x0" );
372
+ #elif defined(__arm__)
373
+ ASSERT_MATCH (result, " memory near r0" );
374
+ #elif defined(__x86_64__)
375
+ ASSERT_MATCH (result, " memory near rdi" );
376
+ #else
377
+ ASSERT_TRUE (false ) << " unsupported architecture" ;
378
+ #endif
379
+ }
380
+
337
381
#if defined(__aarch64__) && defined(ANDROID_EXPERIMENTAL_MTE)
338
382
static void SetTagCheckingLevelSync () {
339
383
int tagged_addr_ctrl = prctl (PR_GET_TAGGED_ADDR_CTRL, 0 , 0 , 0 , 0 );
0 commit comments