Merge changes from topic "microdroid_tombstone_flaky"

* changes:
  Add tombstone upon crash test
  Make sure tombstone is transmitted before VM exit
diff --git a/microdroid/init.rc b/microdroid/init.rc
index be08bbd..b0e5e46 100644
--- a/microdroid/init.rc
+++ b/microdroid/init.rc
@@ -179,6 +179,7 @@
 service tombstone_transmit /system/bin/tombstone_transmit.microdroid -cid 2 -port 2000 -remove_tombstones_after_transmitting
     user root
     group system
+    shutdown critical
 
 service apexd-vm /system/bin/apexd --vm
     user root
diff --git a/microdroid_manager/src/main.rs b/microdroid_manager/src/main.rs
index ae26787..e4694e8 100644
--- a/microdroid_manager/src/main.rs
+++ b/microdroid_manager/src/main.rs
@@ -314,12 +314,6 @@
 
     let config = load_config(Path::new(&metadata.payload_config_path))?;
 
-    // Start tombstone_transmit if enabled
-    if config.export_tombstones {
-        system_properties::write("ctl.start", "tombstone_transmit")
-            .context("Failed to start tombstone_transmit")?;
-    }
-
     if config.extra_apks.len() != verified_data.extra_apks_data.len() {
         return Err(anyhow!(
             "config expects {} extra apks, but found only {}",
@@ -333,6 +327,14 @@
     // TODO(jooyung): wait until sys.boot_completed?
     wait_for_apex_config_done()?;
 
+    // Start tombstone_transmit if enabled
+    if config.export_tombstones {
+        system_properties::write("ctl.start", "tombstone_transmit")
+            .context("Failed to start tombstone_transmit")?;
+    } else {
+        system_properties::write("ctl.stop", "tombstoned").context("Failed to stop tombstoned")?;
+    }
+
     ensure!(
         config.task.is_some(),
         MicrodroidError::InvalidConfig("No task in VM config".to_string())
diff --git a/tests/hostside/java/android/virt/test/MicrodroidTestCase.java b/tests/hostside/java/android/virt/test/MicrodroidTestCase.java
index afccef6..d25868e 100644
--- a/tests/hostside/java/android/virt/test/MicrodroidTestCase.java
+++ b/tests/hostside/java/android/virt/test/MicrodroidTestCase.java
@@ -363,6 +363,46 @@
         shutdownMicrodroid(getDevice(), cid);
     }
 
+    private boolean isTombstoneGeneratedWithConfig(String configPath) throws Exception {
+        // Note this test relies on logcat values being printed by tombstone_transmit on
+        // and the reeceiver on host (virtualization_service)
+        final String cid =
+                startMicrodroid(
+                        getDevice(),
+                        getBuild(),
+                        APK_NAME,
+                        PACKAGE_NAME,
+                        configPath,
+                        /* debug */ true,
+                        minMemorySize(),
+                        Optional.of(NUM_VCPUS),
+                        Optional.of(CPU_AFFINITY));
+        // check until microdroid is shut down
+        CommandRunner android = new CommandRunner(getDevice());
+        android.runWithTimeout(
+                15000,
+                "logcat",
+                "-m",
+                "1",
+                "-e",
+                "'crosvm has exited normally'");
+        // Check that tombstone is received (from host logcat)
+        String result = runOnHost("adb", "-s", getDevice().getSerialNumber(),
+                "logcat", "-d", "-e",
+                "Received [0-9]+ bytes from guest & wrote to tombstone file");
+        return !result.trim().isEmpty();
+    }
+
+    @Test
+    public void testTombstonesAreGeneratedUponCrash() throws Exception {
+        assertTrue(isTombstoneGeneratedWithConfig("assets/vm_config_crash.json"));
+    }
+
+    @Test
+    public void testTombstonesAreNotGeneratedIfNotExported() throws Exception {
+        assertFalse(isTombstoneGeneratedWithConfig("assets/vm_config_crash_no_tombstone.json"));
+    }
+
     @Test
     public void testTombstonesAreBeingForwarded() throws Exception {
         // This test requires rooting. Skip on user builds where rooting is impossible.
diff --git a/tests/testapk/assets/vm_config_crash.json b/tests/testapk/assets/vm_config_crash.json
new file mode 100644
index 0000000..282f25c
--- /dev/null
+++ b/tests/testapk/assets/vm_config_crash.json
@@ -0,0 +1,13 @@
+{
+    "os": {
+      "name": "microdroid"
+    },
+    "task": {
+      "type": "microdroid_launcher",
+      "command": "MicrodroidTestNativeLib.so",
+      "args": [
+        "crash"
+      ]
+    },
+    "export_tombstones": true
+  }
diff --git a/tests/testapk/assets/vm_config_crash_no_tombstone.json b/tests/testapk/assets/vm_config_crash_no_tombstone.json
new file mode 100644
index 0000000..be0983d
--- /dev/null
+++ b/tests/testapk/assets/vm_config_crash_no_tombstone.json
@@ -0,0 +1,13 @@
+{
+    "os": {
+      "name": "microdroid"
+    },
+    "task": {
+      "type": "microdroid_launcher",
+      "command": "MicrodroidTestNativeLib.so",
+      "args": [
+        "crash"
+      ]
+    },
+    "export_tombstones": false
+  }
diff --git a/tests/testapk/src/native/testbinary.cpp b/tests/testapk/src/native/testbinary.cpp
index 422afca..b4fee86 100644
--- a/tests/testapk/src/native/testbinary.cpp
+++ b/tests/testapk/src/native/testbinary.cpp
@@ -181,6 +181,11 @@
     setvbuf(stdout, nullptr, _IONBF, 0);
     setvbuf(stderr, nullptr, _IONBF, 0);
 
+    if (strcmp(argv[1], "crash") == 0) {
+        printf("test crash!!!!\n");
+        abort();
+    }
+
     printf("Hello Microdroid ");
     for (int i = 0; i < argc; i++) {
         printf("%s", argv[i]);