Merge "zip_archive: Remove unused ziparchive-host"
diff --git a/base/strings_test.cpp b/base/strings_test.cpp
index 7ed5b2b..121197c 100644
--- a/base/strings_test.cpp
+++ b/base/strings_test.cpp
@@ -51,6 +51,14 @@
ASSERT_EQ("bar", parts[2]);
}
+TEST(strings, split_with_trailing_empty_part) {
+ std::vector<std::string> parts = android::base::Split("foo,bar,", ",");
+ ASSERT_EQ(3U, parts.size());
+ ASSERT_EQ("foo", parts[0]);
+ ASSERT_EQ("bar", parts[1]);
+ ASSERT_EQ("", parts[2]);
+}
+
TEST(strings, split_null_char) {
std::vector<std::string> parts =
android::base::Split(std::string("foo\0bar", 7), std::string("\0", 1));
diff --git a/bootstat/boot_reason_test.sh b/bootstat/boot_reason_test.sh
index 209e81b..e69db12 100755
--- a/bootstat/boot_reason_test.sh
+++ b/bootstat/boot_reason_test.sh
@@ -194,10 +194,12 @@
sed -n 's/[[]sys[.]\(boot_completed\|logbootcomplete\)[]]: [[]\([01]\)[]]$/\1=\2/p'`
if [ "${vals}" = "`echo boot_completed=1 ; echo logbootcomplete=1`" ]
then
+ sleep 1
break
fi
if [ "${vals}" = "`echo logbootcomplete=1 ; echo boot_completed=1`" ]
then
+ sleep 1
break
fi
fi
@@ -287,6 +289,7 @@
bootstat: Battery level at shutdown 100%
bootstat: Battery level at startup 100%
init : Parsing file /system/etc/init/bootstat.rc...
+init : Parsing file /system/etc/init/bootstat-debug.rc...
init : processing action (persist.test.boot.reason=*) from (/system/etc/init/bootstat-debug.rc:
init : Command 'setprop ro.boot.bootreason \${persist.test.boot.reason}' action=persist.test.boot.reason=* (/system/etc/init/bootstat-debug.rc:
init : processing action (post-fs-data) from (/system/etc/init/bootstat.rc
@@ -566,6 +569,8 @@
esac
adb reboot ${TEST}
wait_for_screen
+ bootloader_reason=`validate_property ro.boot.bootreason`
+ EXPECT_PROPERTY ro.boot.bootreason ${bootloader_reason}
EXPECT_PROPERTY sys.boot.reason ${reason}
EXPECT_PROPERTY persist.sys.boot.reason ${reason}
report_bootstat_logs ${reason}
@@ -868,17 +873,30 @@
- NB: should report reboot,its_just_so_hard
- NB: expect log \"... I bootstat: Unknown boot reason: reboot,its_just_so_hard\"" ]
test_Its_Just_So_Hard_reboot() {
- duration_test
+ if isDebuggable; then # see below
+ duration_test
+ else
+ duration_test `expr ${DURATION_DEFAULT} + ${DURATION_DEFAULT}`
+ fi
adb shell 'reboot "Its Just So Hard"'
wait_for_screen
EXPECT_PROPERTY sys.boot.reason reboot,its_just_so_hard
EXPECT_PROPERTY persist.sys.boot.reason "reboot,Its Just So Hard"
- adb shell su root setprop persist.sys.boot.reason reboot,its_just_so_hard
- if checkDebugBuild; then
- flag=""
+ # Do not leave this test with an illegal value in persist.sys.boot.reason
+ save_ret=${?} # hold on to error code from above two lines
+ if isDebuggable; then # can do this easy, or we can do this hard.
+ adb shell su root setprop persist.sys.boot.reason reboot,its_just_so_hard
+ ( exit ${save_ret} ) # because one can not just do ?=${save_ret}
else
- flag="--allow_failure"
+ report_bootstat_logs reboot,its_just_so_hard # report what we have so far
+ # user build mitigation
+ adb shell reboot its_just_so_hard
+ wait_for_screen
+ ( exit ${save_ret} ) # because one can not just do ?=${save_ret}
+ EXPECT_PROPERTY sys.boot.reason reboot,its_just_so_hard
fi
+ # Ensure persist.sys.boot.reason now valid, failure here acts as a signal
+ # that we could choke up following tests. For example test_properties.
EXPECT_PROPERTY persist.sys.boot.reason reboot,its_just_so_hard ${flag}
report_bootstat_logs reboot,its_just_so_hard
}
diff --git a/bootstat/bootstat.cpp b/bootstat/bootstat.cpp
index 2270133..07d410c 100644
--- a/bootstat/bootstat.cpp
+++ b/bootstat/bootstat.cpp
@@ -223,6 +223,10 @@
{"2sec_reboot", 83},
{"reboot,by_key", 84},
{"reboot,longkey", 85},
+ {"reboot,2sec", 86},
+ {"shutdown,thermal,battery", 87},
+ {"reboot,its_just_so_hard", 88}, // produced by boot_reason_test
+ {"reboot,Its Just So Hard", 89}, // produced by boot_reason_test
};
// Converts a string value representing the reason the system booted to an
@@ -349,10 +353,18 @@
char tounderline(char c) {
return ::isblank(c) ? '_' : c;
}
+
char toprintable(char c) {
return ::isprint(c) ? c : '?';
}
+// Cleanup boot_reason regarding acceptable character set
+void transformReason(std::string& reason) {
+ std::transform(reason.begin(), reason.end(), reason.begin(), ::tolower);
+ std::transform(reason.begin(), reason.end(), reason.begin(), tounderline);
+ std::transform(reason.begin(), reason.end(), reason.begin(), toprintable);
+}
+
const char system_reboot_reason_property[] = "sys.boot.reason";
const char last_reboot_reason_property[] = LAST_REBOOT_REASON_PROPERTY;
const char bootloader_reboot_reason_property[] = "ro.boot.bootreason";
@@ -366,10 +378,7 @@
// If sys.boot.reason == ro.boot.bootreason, let's re-evaluate
if (reason == ret) ret = "";
- // Cleanup boot_reason regarding acceptable character set
- std::transform(reason.begin(), reason.end(), reason.begin(), ::tolower);
- std::transform(reason.begin(), reason.end(), reason.begin(), tounderline);
- std::transform(reason.begin(), reason.end(), reason.begin(), toprintable);
+ transformReason(reason);
// Is the current system boot reason sys.boot.reason valid?
if (!isKnownRebootReason(ret)) ret = "";
@@ -406,6 +415,7 @@
{"shutdown,thermal", "thermal"},
{"warm,s3_wakeup", "s3_wakeup"},
{"hard,hw_reset", "hw_reset"},
+ {"reboot,2sec", "2sec_reboot"},
{"bootloader", ""},
};
@@ -457,18 +467,20 @@
pos += strlen(cmd);
std::string subReason(content.substr(pos, max_reason_length));
for (pos = 0; pos < subReason.length(); ++pos) {
- char c = tounderline(subReason[pos]);
+ char c = subReason[pos];
if (!::isprint(c) || (c == '\'')) {
subReason.erase(pos);
break;
}
- subReason[pos] = ::tolower(c);
}
+ transformReason(subReason);
if (subReason != "") { // Will not land "reboot" as that is too blunt.
if (isKernelRebootReason(subReason)) {
ret = "reboot," + subReason; // User space can't talk kernel reasons.
- } else {
+ } else if (isKnownRebootReason(subReason)) {
ret = subReason;
+ } else {
+ ret = "reboot," + subReason; // legitimize unknown reasons
}
}
}
@@ -560,10 +572,7 @@
// Content buffer no longer will have console data. Beware if more
// checks added below, that depend on parsing console content.
content = GetProperty(last_reboot_reason_property);
- // Cleanup last_boot_reason regarding acceptable character set
- std::transform(content.begin(), content.end(), content.begin(), ::tolower);
- std::transform(content.begin(), content.end(), content.begin(), tounderline);
- std::transform(content.begin(), content.end(), content.begin(), toprintable);
+ transformReason(content);
// Anything in last is better than 'super-blunt' reboot or shutdown.
if ((ret == "") || (ret == "reboot") || (ret == "shutdown") || !isBluntRebootReason(content)) {
diff --git a/init/service.cpp b/init/service.cpp
index 765b61e..45e3f06 100644
--- a/init/service.cpp
+++ b/init/service.cpp
@@ -101,8 +101,22 @@
// It's OK to LOG(FATAL) in this function since it's running in the first
// child process.
- if (mount("", "/proc", "proc", kSafeFlags | MS_REMOUNT, "") == -1) {
- PLOG(FATAL) << "couldn't remount(/proc) for " << service_name;
+
+ // Recursively remount / as slave like zygote does so unmounting and mounting /proc
+ // doesn't interfere with the parent namespace's /proc mount. This will also
+ // prevent any other mounts/unmounts initiated by the service from interfering
+ // with the parent namespace but will still allow mount events from the parent
+ // namespace to propagate to the child.
+ if (mount("rootfs", "/", nullptr, (MS_SLAVE | MS_REC), nullptr) == -1) {
+ PLOG(FATAL) << "couldn't remount(/) recursively as slave for " << service_name;
+ }
+ // umount() then mount() /proc.
+ // Note that it is not sufficient to mount with MS_REMOUNT.
+ if (umount("/proc") == -1) {
+ PLOG(FATAL) << "couldn't umount(/proc) for " << service_name;
+ }
+ if (mount("", "/proc", "proc", kSafeFlags, "") == -1) {
+ PLOG(FATAL) << "couldn't mount(/proc) for " << service_name;
}
if (prctl(PR_SET_NAME, service_name.c_str()) == -1) {
@@ -706,14 +720,20 @@
}
Result<Success> Service::Start() {
+ bool disabled = (flags_ & (SVC_DISABLED | SVC_RESET));
// Starting a service removes it from the disabled or reset state and
// immediately takes it out of the restarting state if it was in there.
flags_ &= (~(SVC_DISABLED|SVC_RESTARTING|SVC_RESET|SVC_RESTART|SVC_DISABLED_START));
// Running processes require no additional work --- if they're in the
// process of exiting, we've ensured that they will immediately restart
- // on exit, unless they are ONESHOT.
+ // on exit, unless they are ONESHOT. For ONESHOT service, if it's in
+ // stopping status, we just set SVC_RESTART flag so it will get restarted
+ // in Reap().
if (flags_ & SVC_RUNNING) {
+ if ((flags_ & SVC_ONESHOT) && disabled) {
+ flags_ |= SVC_RESTART;
+ }
// It is not an error to try to start a service that is already running.
return Success();
}
diff --git a/libbacktrace/UnwindStack.cpp b/libbacktrace/UnwindStack.cpp
index c3f08c8..62e453f 100644
--- a/libbacktrace/UnwindStack.cpp
+++ b/libbacktrace/UnwindStack.cpp
@@ -64,7 +64,7 @@
auto frame = &unwinder_frames[i];
backtrace_frame_data_t* back_frame = &frames->at(cur_frame);
- back_frame->num = frame->num;
+ back_frame->num = frame->num - num_ignore_frames;
back_frame->rel_pc = frame->rel_pc;
back_frame->pc = frame->pc;
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index e5eb9e3..c3e5da0 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -1844,6 +1844,22 @@
UnwindThroughSignal(true, Backtrace::CreateNew, BacktraceMap::CreateNew);
}
+static void TestFrameSkipNumbering(create_func_t create_func, map_create_func_t map_create_func) {
+ std::unique_ptr<BacktraceMap> map(map_create_func(getpid(), false));
+ std::unique_ptr<Backtrace> backtrace(create_func(getpid(), gettid(), map.get()));
+ backtrace->Unwind(1);
+ ASSERT_NE(0U, backtrace->NumFrames());
+ ASSERT_EQ(0U, backtrace->GetFrame(0)->num);
+}
+
+TEST(libbacktrace, unwind_frame_skip_numbering) {
+ TestFrameSkipNumbering(Backtrace::Create, BacktraceMap::Create);
+}
+
+TEST(libbacktrace, unwind_frame_skip_numbering_new) {
+ TestFrameSkipNumbering(Backtrace::CreateNew, BacktraceMap::CreateNew);
+}
+
#if defined(ENABLE_PSS_TESTS)
#include "GetPss.h"