Merge "init-debug.rc: don't mount debugfs"
diff --git a/.clang-format-2 b/.clang-format-2
index fb967d8..aab4665 100644
--- a/.clang-format-2
+++ b/.clang-format-2
@@ -1,8 +1,4 @@
BasedOnStyle: Google
-AllowShortBlocksOnASingleLine: false
-AllowShortFunctionsOnASingleLine: true
-
-AccessModifierOffset: -1
ColumnLimit: 100
CommentPragmas: NOLINT:.*
DerivePointerAlignment: false
diff --git a/.clang-format-4 b/.clang-format-4
index fc4eb1b..1497447 100644
--- a/.clang-format-4
+++ b/.clang-format-4
@@ -1,7 +1,4 @@
BasedOnStyle: Google
-AllowShortBlocksOnASingleLine: false
-AllowShortFunctionsOnASingleLine: false
-
AccessModifierOffset: -2
ColumnLimit: 100
CommentPragmas: NOLINT:.*
diff --git a/adb/.clang-format b/adb/.clang-format
deleted file mode 100644
index fc4eb1b..0000000
--- a/adb/.clang-format
+++ /dev/null
@@ -1,13 +0,0 @@
-BasedOnStyle: Google
-AllowShortBlocksOnASingleLine: false
-AllowShortFunctionsOnASingleLine: false
-
-AccessModifierOffset: -2
-ColumnLimit: 100
-CommentPragmas: NOLINT:.*
-DerivePointerAlignment: false
-IndentWidth: 4
-PointerAlignment: Left
-TabWidth: 4
-UseTab: Never
-PenaltyExcessCharacter: 32
diff --git a/adb/.clang-format b/adb/.clang-format
new file mode 120000
index 0000000..1af4f51
--- /dev/null
+++ b/adb/.clang-format
@@ -0,0 +1 @@
+../.clang-format-4
\ No newline at end of file
diff --git a/base/.clang-format b/base/.clang-format
deleted file mode 100644
index 2b83a1f..0000000
--- a/base/.clang-format
+++ /dev/null
@@ -1,11 +0,0 @@
-BasedOnStyle: Google
-AllowShortBlocksOnASingleLine: false
-AllowShortFunctionsOnASingleLine: false
-
-CommentPragmas: NOLINT:.*
-DerivePointerAlignment: false
-IndentWidth: 2
-PointerAlignment: Left
-TabWidth: 2
-UseTab: Never
-PenaltyExcessCharacter: 32
diff --git a/base/.clang-format b/base/.clang-format
new file mode 120000
index 0000000..fd0645f
--- /dev/null
+++ b/base/.clang-format
@@ -0,0 +1 @@
+../.clang-format-2
\ No newline at end of file
diff --git a/base/file.cpp b/base/file.cpp
index 81b04d7..378a405 100644
--- a/base/file.cpp
+++ b/base/file.cpp
@@ -212,6 +212,20 @@
}
#endif
+#if !defined(_WIN32)
+bool Realpath(const std::string& path, std::string* result) {
+ result->clear();
+
+ char* realpath_buf = realpath(path.c_str(), nullptr);
+ if (realpath_buf == nullptr) {
+ return false;
+ }
+ result->assign(realpath_buf);
+ free(realpath_buf);
+ return true;
+}
+#endif
+
std::string GetExecutablePath() {
#if defined(__linux__)
std::string path;
diff --git a/base/file_test.cpp b/base/file_test.cpp
index 1021326..266131e 100644
--- a/base/file_test.cpp
+++ b/base/file_test.cpp
@@ -159,6 +159,38 @@
#endif
}
+TEST(file, Realpath) {
+#if !defined(_WIN32)
+ TemporaryDir td;
+ std::string basename = android::base::Basename(td.path);
+ std::string dir_name = android::base::Dirname(td.path);
+ std::string base_dir_name = android::base::Basename(dir_name);
+
+ {
+ std::string path = dir_name + "/../" + base_dir_name + "/" + basename;
+ std::string result;
+ ASSERT_TRUE(android::base::Realpath(path, &result));
+ ASSERT_EQ(td.path, result);
+ }
+
+ {
+ std::string path = std::string(td.path) + "/..";
+ std::string result;
+ ASSERT_TRUE(android::base::Realpath(path, &result));
+ ASSERT_EQ(dir_name, result);
+ }
+
+ {
+ errno = 0;
+ std::string path = std::string(td.path) + "/foo.noent";
+ std::string result = "wrong";
+ ASSERT_TRUE(!android::base::Realpath(path, &result));
+ ASSERT_TRUE(result.empty());
+ ASSERT_EQ(ENOENT, errno);
+ }
+#endif
+}
+
TEST(file, GetExecutableDirectory) {
std::string path = android::base::GetExecutableDirectory();
ASSERT_NE("", path);
diff --git a/base/include/android-base/file.h b/base/include/android-base/file.h
index 33d1ab3..651f529 100644
--- a/base/include/android-base/file.h
+++ b/base/include/android-base/file.h
@@ -47,6 +47,7 @@
bool RemoveFileIfExists(const std::string& path, std::string* err = nullptr);
#if !defined(_WIN32)
+bool Realpath(const std::string& path, std::string* result);
bool Readlink(const std::string& path, std::string* result);
#endif
diff --git a/debuggerd/.clang-format b/debuggerd/.clang-format
deleted file mode 100644
index 9b7478c..0000000
--- a/debuggerd/.clang-format
+++ /dev/null
@@ -1,15 +0,0 @@
-BasedOnStyle: Google
-AllowShortBlocksOnASingleLine: false
-AllowShortFunctionsOnASingleLine: false
-
-ColumnLimit: 100
-CommentPragmas: NOLINT:.*
-DerivePointerAlignment: false
-IndentWidth: 2
-ContinuationIndentWidth: 2
-PointerAlignment: Left
-TabWidth: 2
-UseTab: Never
-PenaltyExcessCharacter: 32
-
-Cpp11BracedListStyle: false
diff --git a/debuggerd/.clang-format b/debuggerd/.clang-format
new file mode 120000
index 0000000..fd0645f
--- /dev/null
+++ b/debuggerd/.clang-format
@@ -0,0 +1 @@
+../.clang-format-2
\ No newline at end of file
diff --git a/debuggerd/Android.bp b/debuggerd/Android.bp
index b385ea5..2d6c7f5 100644
--- a/debuggerd/Android.bp
+++ b/debuggerd/Android.bp
@@ -1,5 +1,6 @@
cc_defaults {
name: "debuggerd_defaults",
+ defaults: ["linux_bionic_supported"],
cflags: [
"-Wall",
"-Wextra",
diff --git a/demangle/.clang-format b/demangle/.clang-format
new file mode 120000
index 0000000..fd0645f
--- /dev/null
+++ b/demangle/.clang-format
@@ -0,0 +1 @@
+../.clang-format-2
\ No newline at end of file
diff --git a/fastboot/.clang-format b/fastboot/.clang-format
deleted file mode 100644
index bcb8d8a..0000000
--- a/fastboot/.clang-format
+++ /dev/null
@@ -1,15 +0,0 @@
-BasedOnStyle: Google
-AllowShortBlocksOnASingleLine: false
-AllowShortFunctionsOnASingleLine: Inline
-
-ColumnLimit: 100
-CommentPragmas: NOLINT:.*
-DerivePointerAlignment: false
-IndentWidth: 4
-ContinuationIndentWidth: 8
-ConstructorInitializerIndentWidth: 8
-AccessModifierOffset: -2
-PointerAlignment: Left
-TabWidth: 4
-UseTab: Never
-PenaltyExcessCharacter: 32
diff --git a/fastboot/.clang-format b/fastboot/.clang-format
new file mode 120000
index 0000000..1af4f51
--- /dev/null
+++ b/fastboot/.clang-format
@@ -0,0 +1 @@
+../.clang-format-4
\ No newline at end of file
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index a4a0b52..2927b16 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -1245,20 +1245,17 @@
return 0;
}
-static int do_oem_command(int argc, char **argv)
-{
- char command[256];
+static int do_oem_command(int argc, char** argv) {
if (argc <= 1) return 0;
- command[0] = 0;
- while(1) {
- strcat(command,*argv);
+ std::string command;
+ while (argc > 0) {
+ command += *argv;
skip(1);
- if(argc == 0) break;
- strcat(command," ");
+ if (argc != 0) command += " ";
}
- fb_queue_command(command,"");
+ fb_queue_command(command.c_str(), "");
return 0;
}
diff --git a/init/action.cpp b/init/action.cpp
index 09de81a..1bba0f2 100644
--- a/init/action.cpp
+++ b/init/action.cpp
@@ -246,20 +246,16 @@
}
std::string Action::BuildTriggersString() const {
- std::string result;
+ std::vector<std::string> triggers;
for (const auto& [trigger_name, trigger_value] : property_triggers_) {
- result += trigger_name;
- result += '=';
- result += trigger_value;
- result += ' ';
+ triggers.emplace_back(trigger_name + '=' + trigger_value);
}
if (!event_trigger_.empty()) {
- result += event_trigger_;
- result += ' ';
+ triggers.emplace_back(event_trigger_);
}
- result.pop_back();
- return result;
+
+ return Join(triggers, " && ");
}
void Action::DumpState() const {
@@ -268,7 +264,7 @@
for (const auto& c : commands_) {
std::string cmd_str = c.BuildCommandString();
- LOG(INFO) << " %s" << cmd_str;
+ LOG(INFO) << " " << cmd_str;
}
}
diff --git a/init/builtins.cpp b/init/builtins.cpp
index 9e3489e..0b2e761 100644
--- a/init/builtins.cpp
+++ b/init/builtins.cpp
@@ -494,6 +494,10 @@
parser.ParseConfig(args[i]);
}
}
+
+ // Turning this on and letting the INFO logging be discarded adds 0.2s to
+ // Nexus 9 boot time, so it's disabled by default.
+ if (false) parser.DumpState();
}
/* mount_fstab
diff --git a/init/devices.cpp b/init/devices.cpp
index bd11f5f..405f92e 100644
--- a/init/devices.cpp
+++ b/init/devices.cpp
@@ -390,6 +390,34 @@
return 0;
}
+/* Given a path that may start with a virtual block device, populate
+ * the supplied buffer with the virtual block device ID and return 0.
+ * If it doesn't start with a virtual block device, or there is some
+ * error, return -1 */
+static int find_vbd_device_prefix(const char *path, char *buf, ssize_t buf_sz)
+{
+ const char *start, *end;
+
+ /* Beginning of the prefix is the initial "vbd-" after "/devices/" */
+ if (strncmp(path, "/devices/vbd-", 13))
+ return -1;
+
+ /* End of the prefix is one path '/' later, capturing the
+ virtual block device ID. Example: 768 */
+ start = path + 13;
+ end = strchr(start, '/');
+ if (!end)
+ return -1;
+
+ /* Make sure we have enough room for the string plus null terminator */
+ if (end - start + 1 > buf_sz)
+ return -1;
+
+ strncpy(buf, start, end - start);
+ buf[end - start] = '\0';
+ return 0;
+}
+
static void parse_event(const char *msg, struct uevent *uevent)
{
uevent->action = "";
@@ -516,6 +544,9 @@
} else if (!find_pci_device_prefix(uevent->path, buf, sizeof(buf))) {
device = buf;
type = "pci";
+ } else if (!find_vbd_device_prefix(uevent->path, buf, sizeof(buf))) {
+ device = buf;
+ type = "vbd";
} else {
return NULL;
}
diff --git a/init/init.cpp b/init/init.cpp
index 5ab421b..4e31865 100644
--- a/init/init.cpp
+++ b/init/init.cpp
@@ -1254,6 +1254,10 @@
parser.set_is_odm_etc_init_loaded(true);
}
+ // Turning this on and letting the INFO logging be discarded adds 0.2s to
+ // Nexus 9 boot time, so it's disabled by default.
+ if (false) parser.DumpState();
+
ActionManager& am = ActionManager::GetInstance();
am.QueueEventTrigger("early-init");
diff --git a/init/init_parser.cpp b/init/init_parser.cpp
index 406b339..326ebf2 100644
--- a/init/init_parser.cpp
+++ b/init/init_parser.cpp
@@ -106,10 +106,6 @@
sp.second->EndFile(path);
}
- // Turning this on and letting the INFO logging be discarded adds 0.2s to
- // Nexus 9 boot time, so it's disabled by default.
- if (false) DumpState();
-
LOG(VERBOSE) << "(Parsing " << path << " took " << t << ".)";
return true;
}
diff --git a/libbacktrace/Android.bp b/libbacktrace/Android.bp
index 5b31ecb..0e7c6f3 100644
--- a/libbacktrace/Android.bp
+++ b/libbacktrace/Android.bp
@@ -80,6 +80,18 @@
static_libs: ["libcutils"],
host_ldlibs: ["-lrt"],
},
+ linux_bionic: {
+ enabled: true,
+ srcs: libbacktrace_sources,
+
+ shared_libs: [
+ "libbase",
+ "liblog",
+ "libunwind",
+ ],
+
+ static_libs: ["libcutils"],
+ },
android: {
srcs: libbacktrace_sources,
diff --git a/libcutils/Android.bp b/libcutils/Android.bp
index cf31195..f668f18 100644
--- a/libcutils/Android.bp
+++ b/libcutils/Android.bp
@@ -41,9 +41,12 @@
host_supported: true,
export_include_dirs: ["include"],
target: {
- windows: {
- enabled: true,
- },
+ linux_bionic: {
+ enabled: true,
+ },
+ windows: {
+ enabled: true,
+ },
},
}
@@ -68,11 +71,14 @@
"threads.c",
],
-
target: {
host: {
srcs: ["dlmalloc_stubs.c"],
},
+ linux_bionic: {
+ enabled: true,
+ exclude_srcs: ["dlmalloc_stubs.c"],
+ },
not_windows: {
srcs: libcutils_nonwindows_sources + [
"ashmem-host.c",
diff --git a/libcutils/android_reboot.c b/libcutils/android_reboot.c
index 159a9d4..6bdcc13 100644
--- a/libcutils/android_reboot.c
+++ b/libcutils/android_reboot.c
@@ -209,6 +209,10 @@
LINUX_REBOOT_CMD_RESTART2, arg);
break;
+ case ANDROID_RB_THERMOFF:
+ ret = reboot(RB_POWER_OFF);
+ break;
+
default:
ret = -1;
}
diff --git a/libcutils/include/cutils/android_reboot.h b/libcutils/include/cutils/android_reboot.h
index a3861a0..549f258 100644
--- a/libcutils/include/cutils/android_reboot.h
+++ b/libcutils/include/cutils/android_reboot.h
@@ -25,6 +25,7 @@
#define ANDROID_RB_RESTART 0xDEAD0001
#define ANDROID_RB_POWEROFF 0xDEAD0002
#define ANDROID_RB_RESTART2 0xDEAD0003
+#define ANDROID_RB_THERMOFF 0xDEAD0004
/* Properties */
#define ANDROID_RB_PROPERTY "sys.powerctl"
diff --git a/libprocinfo/.clang-format b/libprocinfo/.clang-format
deleted file mode 100644
index b8c6428..0000000
--- a/libprocinfo/.clang-format
+++ /dev/null
@@ -1,14 +0,0 @@
-BasedOnStyle: Google
-AllowShortBlocksOnASingleLine: false
-AllowShortFunctionsOnASingleLine: false
-
-ColumnLimit: 100
-CommentPragmas: NOLINT:.*
-DerivePointerAlignment: false
-IndentWidth: 2
-PointerAlignment: Left
-TabWidth: 2
-UseTab: Never
-PenaltyExcessCharacter: 32
-
-Cpp11BracedListStyle: false
diff --git a/libprocinfo/.clang-format b/libprocinfo/.clang-format
new file mode 120000
index 0000000..fd0645f
--- /dev/null
+++ b/libprocinfo/.clang-format
@@ -0,0 +1 @@
+../.clang-format-2
\ No newline at end of file
diff --git a/libprocinfo/Android.bp b/libprocinfo/Android.bp
index 8e17f1b..c13ffe9 100644
--- a/libprocinfo/Android.bp
+++ b/libprocinfo/Android.bp
@@ -35,6 +35,9 @@
darwin: {
enabled: false,
},
+ linux_bionic: {
+ enabled: true,
+ },
windows: {
enabled: false,
},
diff --git a/libutils/Android.bp b/libutils/Android.bp
index 0c777b1..2b98fef 100644
--- a/libutils/Android.bp
+++ b/libutils/Android.bp
@@ -17,9 +17,12 @@
host_supported: true,
export_include_dirs: ["include"],
target: {
+ linux_bionic: {
+ enabled: true,
+ },
windows: {
- enabled: true,
- },
+ enabled: true,
+ },
},
}
diff --git a/logcat/tests/logcat_test.cpp b/logcat/tests/logcat_test.cpp
index dad74ee..0895834 100644
--- a/logcat/tests/logcat_test.cpp
+++ b/logcat/tests/logcat_test.cpp
@@ -208,9 +208,9 @@
if ((*ep != '-') && (*ep != '.')) {
continue;
}
- // Find PID field
+ // Find PID field. Look for ': ' or ':[0-9][0-9][0-9]'
while (((ep = strchr(ep, ':'))) && (*++ep != ' ')) {
- ;
+ if (isdigit(ep[0]) && isdigit(ep[1]) && isdigit(ep[2])) break;
}
if (!ep) {
continue;
diff --git a/logd/FlushCommand.cpp b/logd/FlushCommand.cpp
index 5a5c0d9..ff6bff8 100644
--- a/logd/FlushCommand.cpp
+++ b/logd/FlushCommand.cpp
@@ -27,7 +27,7 @@
#include "LogUtils.h"
FlushCommand::FlushCommand(LogReader& reader, bool nonBlock, unsigned long tail,
- unsigned int logMask, pid_t pid, uint64_t start,
+ unsigned int logMask, pid_t pid, log_time start,
uint64_t timeout)
: mReader(reader),
mNonBlock(nonBlock),
@@ -35,7 +35,7 @@
mLogMask(logMask),
mPid(pid),
mStart(start),
- mTimeout((start > 1) ? timeout : 0) {
+ mTimeout((start != log_time::EPOCH) ? timeout : 0) {
}
// runSocketCommand is called once for every open client on the
diff --git a/logd/FlushCommand.h b/logd/FlushCommand.h
index 45cb9c5..7cdd03f 100644
--- a/logd/FlushCommand.h
+++ b/logd/FlushCommand.h
@@ -16,7 +16,7 @@
#ifndef _FLUSH_COMMAND_H
#define _FLUSH_COMMAND_H
-#include <android/log.h>
+#include <private/android_logger.h>
#include <sysutils/SocketClientCommand.h>
class LogBufferElement;
@@ -31,13 +31,13 @@
unsigned long mTail;
unsigned int mLogMask;
pid_t mPid;
- uint64_t mStart;
+ log_time mStart;
uint64_t mTimeout;
public:
explicit FlushCommand(LogReader& mReader, bool nonBlock = false,
unsigned long tail = -1, unsigned int logMask = -1,
- pid_t pid = 0, uint64_t start = 1,
+ pid_t pid = 0, log_time start = log_time::EPOCH,
uint64_t timeout = 0);
virtual void runSocketCommand(SocketClient* client);
diff --git a/logd/LogBuffer.cpp b/logd/LogBuffer.cpp
index 9c634f6..1b79e89 100644
--- a/logd/LogBuffer.cpp
+++ b/logd/LogBuffer.cpp
@@ -180,8 +180,13 @@
if (!avcr) return DIFFERENT;
lenr -= avcr - msgr;
if (lenl != lenr) return DIFFERENT;
- if (fastcmp<memcmp>(avcl + strlen(avc), avcr + strlen(avc), lenl))
+ // TODO: After b/35468874 is addressed, revisit "lenl > strlen(avc)"
+ // condition, it might become superfluous.
+ if (lenl > strlen(avc) &&
+ fastcmp<memcmp>(avcl + strlen(avc), avcr + strlen(avc),
+ lenl - strlen(avc))) {
return DIFFERENT;
+ }
return SAME;
}
@@ -369,18 +374,12 @@
// NB: if end is region locked, place element at end of list
LogBufferElementCollection::iterator it = mLogElements.end();
LogBufferElementCollection::iterator last = it;
- while (last != mLogElements.begin()) {
- --it;
- if ((*it)->getRealTime() <= elem->getRealTime()) {
- break;
- }
- last = it;
- }
-
- if (last == mLogElements.end()) {
+ if (__predict_true(it != mLogElements.begin())) --it;
+ if (__predict_false(it == mLogElements.begin()) ||
+ __predict_true((*it)->getRealTime() <= elem->getRealTime())) {
mLogElements.push_back(elem);
} else {
- uint64_t end = 1;
+ log_time end = log_time::EPOCH;
bool end_set = false;
bool end_always = false;
@@ -394,6 +393,7 @@
end_always = true;
break;
}
+ // it passing mEnd is blocked by the following checks.
if (!end_set || (end <= entry->mEnd)) {
end = entry->mEnd;
end_set = true;
@@ -402,12 +402,20 @@
times++;
}
- if (end_always || (end_set && (end >= (*last)->getSequence()))) {
+ if (end_always || (end_set && (end > (*it)->getRealTime()))) {
mLogElements.push_back(elem);
} else {
+ // should be short as timestamps are localized near end()
+ do {
+ last = it;
+ if (__predict_false(it == mLogElements.begin())) {
+ break;
+ }
+ --it;
+ } while (((*it)->getRealTime() > elem->getRealTime()) &&
+ (!end_set || (end <= (*it)->getRealTime())));
mLogElements.insert(last, elem);
}
-
LogTimeEntry::unlock();
}
@@ -582,12 +590,12 @@
}
void clear(LogBufferElement* element) {
- uint64_t current =
- element->getRealTime().nsec() - (EXPIRE_RATELIMIT * NS_PER_SEC);
+ log_time current =
+ element->getRealTime() - log_time(EXPIRE_RATELIMIT, 0);
for (LogBufferElementMap::iterator it = map.begin(); it != map.end();) {
LogBufferElement* mapElement = it->second;
if ((mapElement->getDropped() >= EXPIRE_THRESHOLD) &&
- (current > mapElement->getRealTime().nsec())) {
+ (current > mapElement->getRealTime())) {
it = map.erase(it);
} else {
++it;
@@ -683,7 +691,7 @@
mLastSet[id] = true;
}
- if (oldest && (oldest->mStart <= element->getSequence())) {
+ if (oldest && (oldest->mStart <= element->getRealTime().nsec())) {
busy = true;
if (oldest->mTimeout.tv_sec || oldest->mTimeout.tv_nsec) {
oldest->triggerReader_Locked();
@@ -775,7 +783,7 @@
while (it != mLogElements.end()) {
LogBufferElement* element = *it;
- if (oldest && (oldest->mStart <= element->getSequence())) {
+ if (oldest && (oldest->mStart <= element->getRealTime().nsec())) {
busy = true;
if (oldest->mTimeout.tv_sec || oldest->mTimeout.tv_nsec) {
oldest->triggerReader_Locked();
@@ -929,7 +937,7 @@
mLastSet[id] = true;
}
- if (oldest && (oldest->mStart <= element->getSequence())) {
+ if (oldest && (oldest->mStart <= element->getRealTime().nsec())) {
busy = true;
if (whitelist) {
break;
@@ -973,7 +981,7 @@
mLastSet[id] = true;
}
- if (oldest && (oldest->mStart <= element->getSequence())) {
+ if (oldest && (oldest->mStart <= element->getRealTime().nsec())) {
busy = true;
if (stats.sizes(id) > (2 * log_buffer_size(id))) {
// kick a misbehaving log reader client off the island
@@ -1066,32 +1074,37 @@
return retval;
}
-uint64_t LogBuffer::flushTo(
- SocketClient* reader, const uint64_t start, bool privileged, bool security,
+log_time LogBuffer::flushTo(
+ SocketClient* reader, const log_time& start, bool privileged, bool security,
int (*filter)(const LogBufferElement* element, void* arg), void* arg) {
LogBufferElementCollection::iterator it;
- uint64_t max = start;
uid_t uid = reader->getUid();
pthread_mutex_lock(&mLogElementsLock);
- if (start <= 1) {
+ if (start == log_time::EPOCH) {
// client wants to start from the beginning
it = mLogElements.begin();
} else {
+ LogBufferElementCollection::iterator last = mLogElements.begin();
+ // 30 second limit to continue search for out-of-order entries.
+ log_time min = start - log_time(30, 0);
// Client wants to start from some specified time. Chances are
// we are better off starting from the end of the time sorted list.
for (it = mLogElements.end(); it != mLogElements.begin();
/* do nothing */) {
--it;
LogBufferElement* element = *it;
- if (element->getSequence() <= start) {
- it++;
+ if (element->getRealTime() > start) {
+ last = it;
+ } else if (element->getRealTime() < min) {
break;
}
}
+ it = last;
}
+ log_time max = start;
// Help detect if the valid message before is from the same source so
// we can differentiate chatty filter types.
pid_t lastTid[LOG_ID_MAX] = { 0 };
@@ -1107,7 +1120,7 @@
continue;
}
- if (element->getSequence() <= start) {
+ if (element->getRealTime() <= start) {
continue;
}
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index 92b0297..fcf6b9a 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -115,7 +115,7 @@
int log(log_id_t log_id, log_time realtime, uid_t uid, pid_t pid, pid_t tid,
const char* msg, unsigned short len);
- uint64_t flushTo(SocketClient* writer, const uint64_t start,
+ log_time flushTo(SocketClient* writer, const log_time& start,
bool privileged, bool security,
int (*filter)(const LogBufferElement* element,
void* arg) = NULL,
diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp
index 5ba3a15..81356fe 100644
--- a/logd/LogBufferElement.cpp
+++ b/logd/LogBufferElement.cpp
@@ -30,7 +30,7 @@
#include "LogReader.h"
#include "LogUtils.h"
-const uint64_t LogBufferElement::FLUSH_ERROR(0);
+const log_time LogBufferElement::FLUSH_ERROR((uint32_t)-1, (uint32_t)-1);
atomic_int_fast64_t LogBufferElement::sequence(1);
LogBufferElement::LogBufferElement(log_id_t log_id, log_time realtime,
@@ -39,7 +39,6 @@
: mUid(uid),
mPid(pid),
mTid(tid),
- mSequence(sequence.fetch_add(1, memory_order_relaxed)),
mRealTime(realtime),
mMsgLen(len),
mLogId(log_id) {
@@ -55,7 +54,6 @@
mUid(elem.mUid),
mPid(elem.mPid),
mTid(elem.mTid),
- mSequence(elem.mSequence),
mRealTime(elem.mRealTime),
mMsgLen(elem.mMsgLen),
mLogId(elem.mLogId) {
@@ -206,7 +204,7 @@
return retval;
}
-uint64_t LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent,
+log_time LogBufferElement::flushTo(SocketClient* reader, LogBuffer* parent,
bool privileged, bool lastSame) {
struct logger_entry_v4 entry;
@@ -229,7 +227,7 @@
if (!mMsg) {
entry.len = populateDroppedMessage(buffer, parent, lastSame);
- if (!entry.len) return mSequence;
+ if (!entry.len) return mRealTime;
iovec[1].iov_base = buffer;
} else {
entry.len = mMsgLen;
@@ -237,7 +235,7 @@
}
iovec[1].iov_len = entry.len;
- uint64_t retval = reader->sendDatav(iovec, 2) ? FLUSH_ERROR : mSequence;
+ log_time retval = reader->sendDatav(iovec, 2) ? FLUSH_ERROR : mRealTime;
if (buffer) free(buffer);
diff --git a/logd/LogBufferElement.h b/logd/LogBufferElement.h
index 43990e8..814ec87 100644
--- a/logd/LogBufferElement.h
+++ b/logd/LogBufferElement.h
@@ -40,7 +40,6 @@
const uint32_t mUid;
const uint32_t mPid;
const uint32_t mTid;
- const uint64_t mSequence;
log_time mRealTime;
char* mMsg;
union {
@@ -96,18 +95,12 @@
const char* getMsg() const {
return mMsg;
}
- uint64_t getSequence(void) const {
- return mSequence;
- }
- static uint64_t getCurrentSequence(void) {
- return sequence.load(memory_order_relaxed);
- }
log_time getRealTime(void) const {
return mRealTime;
}
- static const uint64_t FLUSH_ERROR;
- uint64_t flushTo(SocketClient* writer, LogBuffer* parent, bool privileged,
+ static const log_time FLUSH_ERROR;
+ log_time flushTo(SocketClient* writer, LogBuffer* parent, bool privileged,
bool lastSame);
};
diff --git a/logd/LogKlog.cpp b/logd/LogKlog.cpp
index 9ae95f9..9dfa14e 100644
--- a/logd/LogKlog.cpp
+++ b/logd/LogKlog.cpp
@@ -754,7 +754,7 @@
// eg: [143:healthd]healthd -> [143:healthd]
taglen = etag - tag;
// Mediatek-special printk induced stutter
- const char* mp = strnrchr(tag, ']', taglen);
+ const char* mp = strnrchr(tag, taglen, ']');
if (mp && (++mp < etag)) {
size_t s = etag - mp;
if (((s + s) < taglen) && !fastcmp<memcmp>(mp, mp - 1 - s, s)) {
diff --git a/logd/LogReader.cpp b/logd/LogReader.cpp
index 76f5798..620d4d0 100644
--- a/logd/LogReader.cpp
+++ b/logd/LogReader.cpp
@@ -116,57 +116,70 @@
nonBlock = true;
}
- uint64_t sequence = 1;
- // Convert realtime to sequence number
- if (start != log_time::EPOCH) {
- class LogFindStart {
+ log_time sequence = start;
+ //
+ // This somewhat expensive data validation operation is required
+ // for non-blocking, with timeout. The incoming timestamp must be
+ // in range of the list, if not, return immediately. This is
+ // used to prevent us from from getting stuck in timeout processing
+ // with an invalid time.
+ //
+ // Find if time is really present in the logs, monotonic or real, implicit
+ // conversion from monotonic or real as necessary to perform the check.
+ // Exit in the check loop ASAP as you find a transition from older to
+ // newer, but use the last entry found to ensure overlap.
+ //
+ if (nonBlock && (sequence != log_time::EPOCH) && timeout) {
+ class LogFindStart { // A lambda by another name
+ private:
const pid_t mPid;
const unsigned mLogMask;
- bool startTimeSet;
- log_time& start;
- uint64_t& sequence;
- uint64_t last;
- bool isMonotonic;
+ bool mStartTimeSet;
+ log_time mStart;
+ log_time& mSequence;
+ log_time mLast;
+ bool mIsMonotonic;
public:
- LogFindStart(unsigned logMask, pid_t pid, log_time& start,
- uint64_t& sequence, bool isMonotonic)
+ LogFindStart(pid_t pid, unsigned logMask, log_time& sequence,
+ bool isMonotonic)
: mPid(pid),
mLogMask(logMask),
- startTimeSet(false),
- start(start),
- sequence(sequence),
- last(sequence),
- isMonotonic(isMonotonic) {
+ mStartTimeSet(false),
+ mStart(sequence),
+ mSequence(sequence),
+ mLast(sequence),
+ mIsMonotonic(isMonotonic) {
}
static int callback(const LogBufferElement* element, void* obj) {
LogFindStart* me = reinterpret_cast<LogFindStart*>(obj);
if ((!me->mPid || (me->mPid == element->getPid())) &&
(me->mLogMask & (1 << element->getLogId()))) {
- if (me->start == element->getRealTime()) {
- me->sequence = element->getSequence();
- me->startTimeSet = true;
+ log_time real = element->getRealTime();
+ if (me->mStart == real) {
+ me->mSequence = real;
+ me->mStartTimeSet = true;
return -1;
- } else if (!me->isMonotonic ||
- android::isMonotonic(element->getRealTime())) {
- if (me->start < element->getRealTime()) {
- me->sequence = me->last;
- me->startTimeSet = true;
+ } else if (!me->mIsMonotonic || android::isMonotonic(real)) {
+ if (me->mStart < real) {
+ me->mSequence = me->mLast;
+ me->mStartTimeSet = true;
return -1;
}
- me->last = element->getSequence();
+ me->mLast = real;
} else {
- me->last = element->getSequence();
+ me->mLast = real;
}
}
return false;
}
bool found() {
- return startTimeSet;
+ return mStartTimeSet;
}
- } logFindStart(logMask, pid, start, sequence,
+
+ } logFindStart(pid, logMask, sequence,
logbuf().isMonotonic() && android::isMonotonic(start));
logbuf().flushTo(cli, sequence, FlushCommand::hasReadLogs(cli),
@@ -174,11 +187,8 @@
logFindStart.callback, &logFindStart);
if (!logFindStart.found()) {
- if (nonBlock) {
- doSocketDelete(cli);
- return false;
- }
- sequence = LogBufferElement::getCurrentSequence();
+ doSocketDelete(cli);
+ return false;
}
}
diff --git a/logd/LogTimes.cpp b/logd/LogTimes.cpp
index bdaeb75..04e531f 100644
--- a/logd/LogTimes.cpp
+++ b/logd/LogTimes.cpp
@@ -17,6 +17,8 @@
#include <errno.h>
#include <sys/prctl.h>
+#include <private/android_logger.h>
+
#include "FlushCommand.h"
#include "LogBuffer.h"
#include "LogReader.h"
@@ -26,7 +28,7 @@
LogTimeEntry::LogTimeEntry(LogReader& reader, SocketClient* client,
bool nonBlock, unsigned long tail,
- unsigned int logMask, pid_t pid, uint64_t start,
+ unsigned int logMask, pid_t pid, log_time start,
uint64_t timeout)
: mRefCount(1),
mRelease(false),
@@ -42,7 +44,7 @@
mClient(client),
mStart(start),
mNonBlock(nonBlock),
- mEnd(LogBufferElement::getCurrentSequence()) {
+ mEnd(log_time(android_log_clockid())) {
mTimeout.tv_sec = timeout / NS_PER_SEC;
mTimeout.tv_nsec = timeout % NS_PER_SEC;
pthread_cond_init(&threadTriggeredCondition, NULL);
@@ -132,7 +134,7 @@
lock();
- uint64_t start = me->mStart;
+ log_time start = me->mStart;
while (me->threadRunning && !me->isError_Locked()) {
if (me->mTimeout.tv_sec || me->mTimeout.tv_nsec) {
@@ -163,7 +165,7 @@
break;
}
- me->mStart = start + 1;
+ me->mStart = start + log_time(0, 1);
if (me->mNonBlock || !me->threadRunning || me->isError_Locked()) {
break;
@@ -198,7 +200,7 @@
}
if (me->mCount == 0) {
- me->mStart = element->getSequence();
+ me->mStart = element->getRealTime();
}
if ((!me->mPid || (me->mPid == element->getPid())) &&
@@ -217,7 +219,7 @@
LogTimeEntry::lock();
- me->mStart = element->getSequence();
+ me->mStart = element->getRealTime();
if (me->skipAhead[element->getLogId()]) {
me->skipAhead[element->getLogId()]--;
diff --git a/logd/LogTimes.h b/logd/LogTimes.h
index 23fdf4e..9a3ddab 100644
--- a/logd/LogTimes.h
+++ b/logd/LogTimes.h
@@ -51,13 +51,13 @@
public:
LogTimeEntry(LogReader& reader, SocketClient* client, bool nonBlock,
unsigned long tail, unsigned int logMask, pid_t pid,
- uint64_t start, uint64_t timeout);
+ log_time start, uint64_t timeout);
SocketClient* mClient;
- uint64_t mStart;
+ log_time mStart;
struct timespec mTimeout;
const bool mNonBlock;
- const uint64_t mEnd; // only relevant if mNonBlock
+ const log_time mEnd; // only relevant if mNonBlock
// Protect List manipulations
static void lock(void) {