Merge "Fix memory ordering issues; document IMemory peculiarities"
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 0d8a0ea..db2e392 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -36,6 +36,7 @@
#include <android-base/stringprintf.h>
#include <android-base/unique_fd.h>
+#include <android-base/file.h>
#include <cutils/properties.h>
#include "private/android_filesystem_config.h"
@@ -184,6 +185,118 @@
closedir(d);
}
+// return pid of a userspace process. If not found or error, return 0.
+static unsigned int pid_of_process(const char* ps_name) {
+ DIR *proc_dir;
+ struct dirent *ps;
+ unsigned int pid;
+ std::string cmdline;
+
+ if (!(proc_dir = opendir("/proc"))) {
+ MYLOGE("Can't open /proc\n");
+ return 0;
+ }
+
+ while ((ps = readdir(proc_dir))) {
+ if (!(pid = atoi(ps->d_name))) {
+ continue;
+ }
+ android::base::ReadFileToString("/proc/"
+ + std::string(ps->d_name) + "/cmdline", &cmdline);
+ if (cmdline.find(ps_name) == std::string::npos) {
+ continue;
+ } else {
+ closedir(proc_dir);
+ return pid;
+ }
+ }
+ closedir(proc_dir);
+ return 0;
+}
+
+// dump anrd's trace and add to the zip file.
+// 1. check if anrd is running on this device.
+// 2. send a SIGUSR1 to its pid which will dump anrd's trace.
+// 3. wait until the trace generation completes and add to the zip file.
+static bool dump_anrd_trace() {
+ unsigned int pid;
+ char buf[50], path[PATH_MAX];
+ struct dirent *trace;
+ struct stat st;
+ DIR *trace_dir;
+ long max_ctime = 0;
+ long long cur_size = 0;
+ const char *trace_path = "/data/misc/anrd/";
+
+ if (!zip_writer) {
+ MYLOGE("Not dumping anrd trace because zip_writer is not set\n");
+ return false;
+ }
+
+ // find anrd's pid if it is running.
+ pid = pid_of_process("/system/xbin/anrd");
+
+ if (pid > 0) {
+ // send SIGUSR1 to the anrd to generate a trace.
+ sprintf(buf, "%u", pid);
+ if (run_command("ANRD_DUMP", 1, "kill", "-SIGUSR1", buf, NULL)) {
+ MYLOGE("anrd signal timed out. Please manually collect trace\n");
+ return false;
+ }
+
+ // identify the trace file by its creation time.
+ if (!(trace_dir = opendir(trace_path))) {
+ MYLOGE("Can't open trace file under %s\n", trace_path);
+ }
+ while ((trace = readdir(trace_dir))) {
+ if (strcmp(trace->d_name, ".") == 0
+ || strcmp(trace->d_name, "..") == 0) {
+ continue;
+ }
+ sprintf(path, "%s%s", trace_path, trace->d_name);
+ if (stat(path, &st) == 0) {
+ if (st.st_ctime > max_ctime) {
+ max_ctime = st.st_ctime;
+ sprintf(buf, "%s", trace->d_name);
+ }
+ }
+ }
+ closedir(trace_dir);
+
+ // Wait until the dump completes by checking the size of the trace.
+ if (max_ctime > 0) {
+ sprintf(path, "%s%s", trace_path, buf);
+ while(true) {
+ sleep(1);
+ if (stat(path, &st) == 0) {
+ if (st.st_size == cur_size) {
+ break;
+ } else if (st.st_size > cur_size) {
+ cur_size = st.st_size;
+ } else {
+ return false;
+ }
+ } else {
+ MYLOGE("Cant stat() %s anymore\n", path);
+ return false;
+ }
+ }
+ // Add to the zip file.
+ if (!add_zip_entry("anrd_trace.txt", path)) {
+ MYLOGE("Unable to add anrd_trace file %s to zip file\n", path);
+ } else {
+ if (remove(path)) {
+ MYLOGE("Error removing anrd_trace file %s: %s", path, strerror(errno));
+ }
+ return true;
+ }
+ } else {
+ MYLOGE("Can't stats any trace file under %s\n", trace_path);
+ }
+ }
+ return false;
+}
+
static void dump_systrace() {
if (!zip_writer) {
MYLOGD("Not dumping systrace because zip_writer is not set\n");
@@ -1043,7 +1156,7 @@
printf("== Final progress (pid %d): %d/%d (originally %d)\n",
getpid(), progress, weight_total, WEIGHT_TOTAL);
printf("========================================================\n");
- printf("== dumpstate: done\n");
+ printf("== dumpstate: done (id %lu)\n", id);
printf("========================================================\n");
}
@@ -1080,6 +1193,13 @@
*/
static bool finish_zip_file(const std::string& bugreport_name, const std::string& bugreport_path,
const std::string& log_path, time_t now) {
+ // Final timestamp
+ char date[80];
+ time_t the_real_now_please_stand_up = time(nullptr);
+ strftime(date, sizeof(date), "%Y/%m/%d %H:%M:%S", localtime(&the_real_now_please_stand_up));
+ MYLOGD("dumpstate id %lu finished around %s (%ld s)\n", id, date,
+ the_real_now_please_stand_up - now);
+
if (!add_zip_entry(bugreport_name, bugreport_path)) {
MYLOGE("Failed to add text entry to .zip file\n");
return false;
@@ -1166,7 +1286,7 @@
int is_remote_mode = 0;
std::string version = VERSION_DEFAULT;
- now = time(NULL);
+ now = time(nullptr);
MYLOGI("begin\n");
@@ -1418,7 +1538,11 @@
print_header(version);
// Dumps systrace right away, otherwise it will be filled with unnecessary events.
- dump_systrace();
+ // First try to dump anrd trace if the daemon is running. Otherwise, dump
+ // the raw trace.
+ if (!dump_anrd_trace()) {
+ dump_systrace();
+ }
// TODO: Drop root user and move into dumpstate() once b/28633932 is fixed.
dump_raft();
@@ -1568,7 +1692,7 @@
}
MYLOGD("Final progress: %d/%d (originally %d)\n", progress, weight_total, WEIGHT_TOTAL);
- MYLOGI("done\n");
+ MYLOGI("done (id %lu)\n", id);
if (is_redirecting) {
fclose(stderr);
diff --git a/cmds/installd/otapreopt_script.sh b/cmds/installd/otapreopt_script.sh
index 8af4a90..f950276 100644
--- a/cmds/installd/otapreopt_script.sh
+++ b/cmds/installd/otapreopt_script.sh
@@ -24,6 +24,19 @@
# Maximum number of packages/steps.
MAXIMUM_PACKAGES=1000
+# First ensure the system is booted. This is to work around issues when cmd would
+# infinitely loop trying to get a service manager (which will never come up in that
+# mode). b/30797145
+BOOT_PROPERTY_NAME="dev.bootcomplete"
+
+BOOT_COMPLETE=$(getprop $BOOT_PROPERTY_NAME)
+if [ "$BOOT_COMPLETE" != "1" ] ; then
+ echo "Error: boot-complete not detected."
+ # We must return 0 to not block sideload.
+ exit 0
+fi
+
+
# Compute target slot suffix.
# TODO: Once bootctl is not restricted, we should query from there. Or get this from
# update_engine as a parameter.
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 319d1d9..d42bb82 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -16,8 +16,6 @@
#define LOG_TAG "ProcessState"
-#include <cutils/process_name.h>
-
#include <binder/ProcessState.h>
#include <utils/Atomic.h>
diff --git a/services/sensorservice/SensorEventConnection.cpp b/services/sensorservice/SensorEventConnection.cpp
index c1e1bad..f2f1444 100644
--- a/services/sensorservice/SensorEventConnection.cpp
+++ b/services/sensorservice/SensorEventConnection.cpp
@@ -206,7 +206,7 @@
status_t SensorService::SensorEventConnection::sendEvents(
sensors_event_t const* buffer, size_t numEvents,
sensors_event_t* scratch,
- SensorEventConnection const * const * mapFlushEventsToConnections) {
+ wp<const SensorEventConnection> const * mapFlushEventsToConnections) {
// filter out events not for this connection
int count = 0;
Mutex::Autolock _l(mConnectionLock);
@@ -234,7 +234,7 @@
FlushInfo& flushInfo = mSensorInfo.editValueAt(index);
// Check if there is a pending flush_complete event for this sensor on this connection.
if (buffer[i].type == SENSOR_TYPE_META_DATA && flushInfo.mFirstFlushPending == true &&
- this == mapFlushEventsToConnections[i]) {
+ mapFlushEventsToConnections[i] == this) {
flushInfo.mFirstFlushPending = false;
ALOGD_IF(DEBUG_CONNECTIONS, "First flush event for sensor==%d ",
buffer[i].meta_data.sensor);
@@ -255,7 +255,7 @@
// from the same sensor_handle AND the current connection is mapped to the
// corresponding flush_complete_event.
if (buffer[i].type == SENSOR_TYPE_META_DATA) {
- if (this == mapFlushEventsToConnections[i]) {
+ if (mapFlushEventsToConnections[i] == this) {
scratch[count++] = buffer[i];
}
++i;
diff --git a/services/sensorservice/SensorEventConnection.h b/services/sensorservice/SensorEventConnection.h
index b796cc0..883c16e 100644
--- a/services/sensorservice/SensorEventConnection.h
+++ b/services/sensorservice/SensorEventConnection.h
@@ -52,7 +52,7 @@
bool isDataInjectionMode, const String16& opPackageName);
status_t sendEvents(sensors_event_t const* buffer, size_t count, sensors_event_t* scratch,
- SensorEventConnection const * const * mapFlushEventsToConnections = NULL);
+ wp<const SensorEventConnection> const * mapFlushEventsToConnections = NULL);
bool hasSensor(int32_t handle) const;
bool hasAnySensor() const;
bool hasOneShotSensors() const;
diff --git a/services/sensorservice/SensorRecord.cpp b/services/sensorservice/SensorRecord.cpp
index 644cfb0..53fb9de 100644
--- a/services/sensorservice/SensorRecord.cpp
+++ b/services/sensorservice/SensorRecord.cpp
@@ -21,13 +21,13 @@
namespace android {
SensorService::SensorRecord::SensorRecord(
- const sp<SensorEventConnection>& connection)
+ const sp<const SensorEventConnection>& connection)
{
mConnections.add(connection);
}
bool SensorService::SensorRecord::addConnection(
- const sp<SensorEventConnection>& connection)
+ const sp<const SensorEventConnection>& connection)
{
if (mConnections.indexOf(connection) < 0) {
mConnections.add(connection);
@@ -37,16 +37,16 @@
}
bool SensorService::SensorRecord::removeConnection(
- const wp<SensorEventConnection>& connection)
+ const wp<const SensorEventConnection>& connection)
{
ssize_t index = mConnections.indexOf(connection);
if (index >= 0) {
mConnections.removeItemsAt(index, 1);
}
// Remove this connections from the queue of flush() calls made on this sensor.
- for (Vector< wp<SensorEventConnection> >::iterator it = mPendingFlushConnections.begin();
+ for (Vector< wp<const SensorEventConnection> >::iterator it = mPendingFlushConnections.begin();
it != mPendingFlushConnections.end(); ) {
- if (it->unsafe_get() == connection.unsafe_get()) {
+ if (*it == connection) {
it = mPendingFlushConnections.erase(it);
} else {
++it;
@@ -56,7 +56,7 @@
}
void SensorService::SensorRecord::addPendingFlushConnection(
- const sp<SensorEventConnection>& connection) {
+ const sp<const SensorEventConnection>& connection) {
mPendingFlushConnections.add(connection);
}
@@ -66,10 +66,10 @@
}
}
-SensorService::SensorEventConnection *
+wp<const SensorService::SensorEventConnection>
SensorService::SensorRecord::getFirstPendingFlushConnection() {
if (mPendingFlushConnections.size() > 0) {
- return mPendingFlushConnections[0].unsafe_get();
+ return mPendingFlushConnections[0];
}
return NULL;
}
diff --git a/services/sensorservice/SensorRecord.h b/services/sensorservice/SensorRecord.h
index 29b970d..5a35410 100644
--- a/services/sensorservice/SensorRecord.h
+++ b/services/sensorservice/SensorRecord.h
@@ -25,20 +25,20 @@
class SensorService::SensorRecord {
public:
- SensorRecord(const sp<SensorEventConnection>& connection);
- bool addConnection(const sp<SensorEventConnection>& connection);
- bool removeConnection(const wp<SensorEventConnection>& connection);
+ SensorRecord(const sp<const SensorEventConnection>& connection);
+ bool addConnection(const sp<const SensorEventConnection>& connection);
+ bool removeConnection(const wp<const SensorEventConnection>& connection);
size_t getNumConnections() const { return mConnections.size(); }
- void addPendingFlushConnection(const sp<SensorEventConnection>& connection);
+ void addPendingFlushConnection(const sp<const SensorEventConnection>& connection);
void removeFirstPendingFlushConnection();
- SensorEventConnection * getFirstPendingFlushConnection();
+ wp<const SensorEventConnection> getFirstPendingFlushConnection();
void clearAllPendingFlushConnections();
private:
- SortedVector< wp<SensorEventConnection> > mConnections;
+ SortedVector< wp<const SensorEventConnection> > mConnections;
// A queue of all flush() calls made on this sensor. Flush complete events
// will be sent in this order.
- Vector< wp<SensorEventConnection> > mPendingFlushConnections;
+ Vector< wp<const SensorEventConnection> > mPendingFlushConnections;
};
}
diff --git a/services/sensorservice/SensorService.cpp b/services/sensorservice/SensorService.cpp
index a24740b..dbd0624 100644
--- a/services/sensorservice/SensorService.cpp
+++ b/services/sensorservice/SensorService.cpp
@@ -260,7 +260,7 @@
const size_t minBufferSize = SensorEventQueue::MAX_RECEIVE_BUFFER_EVENT_COUNT;
mSensorEventBuffer = new sensors_event_t[minBufferSize];
mSensorEventScratch = new sensors_event_t[minBufferSize];
- mMapFlushEventsToConnections = new SensorEventConnection const * [minBufferSize];
+ mMapFlushEventsToConnections = new wp<const SensorEventConnection> [minBufferSize];
mCurrentOperatingMode = NORMAL;
mNextSensorRegIndex = 0;
diff --git a/services/sensorservice/SensorService.h b/services/sensorservice/SensorService.h
index 343796a..e969d8a 100644
--- a/services/sensorservice/SensorService.h
+++ b/services/sensorservice/SensorService.h
@@ -237,7 +237,7 @@
SortedVector< wp<SensorEventConnection> > mActiveConnections;
bool mWakeLockAcquired;
sensors_event_t *mSensorEventBuffer, *mSensorEventScratch;
- SensorEventConnection const **mMapFlushEventsToConnections;
+ wp<const SensorEventConnection> * mMapFlushEventsToConnections;
std::unordered_map<int, RecentEventLogger*> mRecentEvent;
Mode mCurrentOperatingMode;