Merge "Update partition.*.verified even with ro.boot.veritymode set"
diff --git a/adb/Android.mk b/adb/Android.mk
index f030041..7977009 100644
--- a/adb/Android.mk
+++ b/adb/Android.mk
@@ -238,12 +238,11 @@
-D_GNU_SOURCE \
-Wno-deprecated-declarations \
-ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
-LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1
-endif
+LOCAL_CFLAGS += -DALLOW_ADBD_NO_AUTH=$(if $(filter userdebug eng,$(TARGET_BUILD_VARIANT)),1,0)
ifneq (,$(filter userdebug eng,$(TARGET_BUILD_VARIANT)))
LOCAL_CFLAGS += -DALLOW_ADBD_DISABLE_VERITY=1
+LOCAL_CFLAGS += -DALLOW_ADBD_ROOT=1
endif
LOCAL_MODULE := adbd
diff --git a/adb/adb.cpp b/adb/adb.cpp
index 9af1586..2e59634 100644
--- a/adb/adb.cpp
+++ b/adb/adb.cpp
@@ -431,9 +431,9 @@
parse_banner(reinterpret_cast<const char*>(p->data), t);
- if (HOST || !auth_enabled) {
+ if (HOST || !auth_required) {
handle_online(t);
- if(!HOST) send_connect(t);
+ if (!HOST) send_connect(t);
} else {
send_auth_request(t);
}
@@ -835,6 +835,14 @@
return 0;
}
+#if ADB_HOST
+static int SendOkay(int fd, const std::string& s) {
+ SendOkay(fd);
+ SendProtocolString(fd, s);
+ return 0;
+}
+#endif
+
int handle_host_request(const char* service, TransportType type,
const char* serial, int reply_fd, asocket* s) {
if (strcmp(service, "kill") == 0) {
@@ -845,7 +853,6 @@
}
#if ADB_HOST
- atransport *transport = NULL;
// "transport:" is used for switching transport with a specified serial number
// "transport-usb:" is used for switching transport to the only USB transport
// "transport-local:" is used for switching transport to the only local transport
@@ -864,11 +871,10 @@
serial = service;
}
- std::string error_msg = "unknown failure";
- transport = acquire_one_transport(kCsAny, type, serial, &error_msg);
-
- if (transport) {
- s->transport = transport;
+ std::string error_msg;
+ atransport* t = acquire_one_transport(kCsAny, type, serial, &error_msg);
+ if (t != nullptr) {
+ s->transport = t;
SendOkay(reply_fd);
} else {
SendFail(reply_fd, error_msg);
@@ -883,9 +889,7 @@
D("Getting device list...\n");
std::string device_list = list_transports(long_listing);
D("Sending device list...\n");
- SendOkay(reply_fd);
- SendProtocolString(reply_fd, device_list);
- return 0;
+ return SendOkay(reply_fd, device_list);
}
return 1;
}
@@ -905,8 +909,7 @@
snprintf(hostbuf, sizeof(hostbuf) - 1, "%s:5555", serial);
serial = hostbuf;
}
- atransport *t = find_transport(serial);
-
+ atransport* t = find_transport(serial);
if (t) {
unregister_transport(t);
} else {
@@ -914,52 +917,38 @@
}
}
- SendOkay(reply_fd);
- SendProtocolString(reply_fd, buffer);
- return 0;
+ return SendOkay(reply_fd, buffer);
}
// returns our value for ADB_SERVER_VERSION
if (!strcmp(service, "version")) {
- SendOkay(reply_fd);
- SendProtocolString(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION));
- return 0;
+ return SendOkay(reply_fd, android::base::StringPrintf("%04x", ADB_SERVER_VERSION));
}
- if(!strncmp(service,"get-serialno",strlen("get-serialno"))) {
- const char *out = "unknown";
- transport = acquire_one_transport(kCsAny, type, serial, NULL);
- if (transport && transport->serial) {
- out = transport->serial;
- }
- SendOkay(reply_fd);
- SendProtocolString(reply_fd, out);
- return 0;
+ // These always report "unknown" rather than the actual error, for scripts.
+ if (!strcmp(service, "get-serialno")) {
+ std::string ignored;
+ atransport* t = acquire_one_transport(kCsAny, type, serial, &ignored);
+ return SendOkay(reply_fd, (t && t->serial) ? t->serial : "unknown");
}
- if(!strncmp(service,"get-devpath",strlen("get-devpath"))) {
- const char *out = "unknown";
- transport = acquire_one_transport(kCsAny, type, serial, NULL);
- if (transport && transport->devpath) {
- out = transport->devpath;
- }
- SendOkay(reply_fd);
- SendProtocolString(reply_fd, out);
- return 0;
+ if (!strcmp(service, "get-devpath")) {
+ std::string ignored;
+ atransport* t = acquire_one_transport(kCsAny, type, serial, &ignored);
+ return SendOkay(reply_fd, (t && t->devpath) ? t->devpath : "unknown");
}
+ if (!strcmp(service, "get-state")) {
+ std::string ignored;
+ atransport* t = acquire_one_transport(kCsAny, type, serial, &ignored);
+ return SendOkay(reply_fd, t ? t->connection_state_name() : "unknown");
+ }
+
// indicates a new emulator instance has started
- if (!strncmp(service,"emulator:",9)) {
+ if (!strncmp(service, "emulator:", 9)) {
int port = atoi(service+9);
local_connect(port);
/* we don't even need to send a reply */
return 0;
}
-
- if(!strncmp(service,"get-state",strlen("get-state"))) {
- transport = acquire_one_transport(kCsAny, type, serial, NULL);
- SendOkay(reply_fd);
- SendProtocolString(reply_fd, transport->connection_state_name());
- return 0;
- }
#endif // ADB_HOST
int ret = handle_forward_request(service, type, serial, reply_fd);
diff --git a/adb/adb_auth.cpp b/adb/adb_auth.cpp
index dc01825..cff26d6 100644
--- a/adb/adb_auth.cpp
+++ b/adb/adb_auth.cpp
@@ -28,7 +28,7 @@
#include "adb.h"
#include "transport.h"
-int auth_enabled = 0;
+bool auth_required = true;
void send_auth_request(atransport *t)
{
diff --git a/adb/adb_auth.h b/adb/adb_auth.h
index 1e1978d..a13604a 100644
--- a/adb/adb_auth.h
+++ b/adb/adb_auth.h
@@ -19,7 +19,7 @@
#include "adb.h"
-extern int auth_enabled;
+extern bool auth_required;
int adb_auth_keygen(const char* filename);
void adb_auth_verified(atransport *t);
diff --git a/adb/adb_listeners.cpp b/adb/adb_listeners.cpp
index a335eec..641b537 100644
--- a/adb/adb_listeners.cpp
+++ b/adb/adb_listeners.cpp
@@ -118,7 +118,7 @@
return socket_loopback_server(port, SOCK_STREAM);
}
}
-#ifndef HAVE_WIN32_IPC /* no Unix-domain sockets on Win32 */
+#if !defined(_WIN32) // No Unix-domain sockets on Windows.
// It's nonsensical to support the "reserved" space on the adb host side
if (!strncmp(name, "local:", 6)) {
return socket_local_server(name + 6, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM);
diff --git a/adb/daemon/main.cpp b/adb/daemon/main.cpp
index d7fa362..157c97b 100644
--- a/adb/daemon/main.cpp
+++ b/adb/daemon/main.cpp
@@ -125,11 +125,12 @@
// descriptor will always be open.
adbd_cloexec_auth_socket();
- auth_enabled = property_get_bool("ro.adb.secure", 0) != 0;
- if (auth_enabled) {
- adbd_auth_init();
+ if (ALLOW_ADBD_NO_AUTH && property_get_bool("ro.adb.secure", 0) == 0) {
+ auth_required = false;
}
+ adbd_auth_init();
+
// Our external storage path may be different than apps, since
// we aren't able to bind mount after dropping root.
const char* adb_external_storage = getenv("ADB_EXTERNAL_STORAGE");
diff --git a/adb/protocol.txt b/adb/protocol.txt
index c9d3c24..333e7e7 100644
--- a/adb/protocol.txt
+++ b/adb/protocol.txt
@@ -133,7 +133,7 @@
---- WRITE(0, remote-id, "data") ----------------------------------------
+--- WRITE(local-id, remote-id, "data") ---------------------------------
The WRITE message sends data to the recipient's stream identified by
remote-id. The payload MUST be <= maxdata in length.
diff --git a/adb/remount_service.cpp b/adb/remount_service.cpp
index 3a4d2da..2893263 100644
--- a/adb/remount_service.cpp
+++ b/adb/remount_service.cpp
@@ -33,9 +33,12 @@
#include "adb_io.h"
#include "adb_utils.h"
#include "cutils/properties.h"
+#include "fs_mgr.h"
+
+const std::string kFstab_Prefix = "/fstab.";
// Returns the device used to mount a directory in /proc/mounts.
-static std::string find_mount(const char* dir) {
+static std::string find_proc_mount(const char* dir) {
std::unique_ptr<FILE, int(*)(FILE*)> fp(setmntent("/proc/mounts", "r"), endmntent);
if (!fp) {
return "";
@@ -50,6 +53,29 @@
return "";
}
+// Returns the device used to mount a directory in the fstab.
+static std::string find_fstab_mount(const char* dir) {
+ char propbuf[PROPERTY_VALUE_MAX];
+
+ property_get("ro.hardware", propbuf, "");
+ std::string fstab_filename = kFstab_Prefix + propbuf;
+ struct fstab* fstab = fs_mgr_read_fstab(fstab_filename.c_str());
+ struct fstab_rec* rec = fs_mgr_get_entry_for_mount_point(fstab, dir);
+ std::string dev = rec ? std::string(rec->blk_device) : "";
+ fs_mgr_free_fstab(fstab);
+ return dev;
+}
+
+// The proc entry for / is full of lies, so check fstab instead.
+// /proc/mounts lists rootfs and /dev/root, neither of which is what we want.
+static std::string find_mount(const char* dir) {
+ if (strcmp(dir, "/") == 0) {
+ return find_fstab_mount(dir);
+ } else {
+ return find_proc_mount(dir);
+ }
+}
+
bool make_block_device_writable(const std::string& dev) {
int fd = unix_open(dev.c_str(), O_RDONLY | O_CLOEXEC);
if (fd == -1) {
@@ -112,7 +138,13 @@
}
bool success = true;
- success &= remount_partition(fd, "/system");
+ property_get("ro.build.system_root_image", prop_buf, "");
+ bool system_root = !strcmp(prop_buf, "true");
+ if (system_root) {
+ success &= remount_partition(fd, "/");
+ } else {
+ success &= remount_partition(fd, "/system");
+ }
success &= remount_partition(fd, "/vendor");
success &= remount_partition(fd, "/oem");
diff --git a/adb/services.cpp b/adb/services.cpp
index 2fd75ab..227f22a 100644
--- a/adb/services.cpp
+++ b/adb/services.cpp
@@ -528,7 +528,7 @@
std::string error_msg = "unknown error";
atransport* t = acquire_one_transport(sinfo->state, sinfo->transport_type, sinfo->serial,
&error_msg);
- if (t != 0) {
+ if (t != nullptr) {
SendOkay(fd);
} else {
SendFail(fd, error_msg);
diff --git a/adb/transport.cpp b/adb/transport.cpp
index 379c702..274449b 100644
--- a/adb/transport.cpp
+++ b/adb/transport.cpp
@@ -731,12 +731,12 @@
int ambiguous = 0;
retry:
- if (error_out) *error_out = android::base::StringPrintf("device '%s' not found", serial);
+ *error_out = serial ? android::base::StringPrintf("device '%s' not found", serial) : "no devices found";
adb_mutex_lock(&transport_lock);
for (auto t : transport_list) {
if (t->connection_state == kCsNoPerm) {
- if (error_out) *error_out = "insufficient permissions for device";
+ *error_out = "insufficient permissions for device";
continue;
}
@@ -748,7 +748,7 @@
qual_match(serial, "model:", t->model, true) ||
qual_match(serial, "device:", t->device, false)) {
if (result) {
- if (error_out) *error_out = "more than one device";
+ *error_out = "more than one device";
ambiguous = 1;
result = NULL;
break;
@@ -758,7 +758,7 @@
} else {
if (type == kTransportUsb && t->type == kTransportUsb) {
if (result) {
- if (error_out) *error_out = "more than one device";
+ *error_out = "more than one device";
ambiguous = 1;
result = NULL;
break;
@@ -766,7 +766,7 @@
result = t;
} else if (type == kTransportLocal && t->type == kTransportLocal) {
if (result) {
- if (error_out) *error_out = "more than one emulator";
+ *error_out = "more than one emulator";
ambiguous = 1;
result = NULL;
break;
@@ -774,7 +774,7 @@
result = t;
} else if (type == kTransportAny) {
if (result) {
- if (error_out) *error_out = "more than one device/emulator";
+ *error_out = "more than one device/emulator";
ambiguous = 1;
result = NULL;
break;
@@ -787,33 +787,31 @@
if (result) {
if (result->connection_state == kCsUnauthorized) {
- if (error_out) {
- *error_out = "device unauthorized.\n";
- char* ADB_VENDOR_KEYS = getenv("ADB_VENDOR_KEYS");
- *error_out += "This adbd's $ADB_VENDOR_KEYS is ";
- *error_out += ADB_VENDOR_KEYS ? ADB_VENDOR_KEYS : "not set";
- *error_out += "; try 'adb kill-server' if that seems wrong.\n";
- *error_out += "Otherwise check for a confirmation dialog on your device.";
- }
+ *error_out = "device unauthorized.\n";
+ char* ADB_VENDOR_KEYS = getenv("ADB_VENDOR_KEYS");
+ *error_out += "This adbd's $ADB_VENDOR_KEYS is ";
+ *error_out += ADB_VENDOR_KEYS ? ADB_VENDOR_KEYS : "not set";
+ *error_out += "; try 'adb kill-server' if that seems wrong.\n";
+ *error_out += "Otherwise check for a confirmation dialog on your device.";
result = NULL;
}
/* offline devices are ignored -- they are either being born or dying */
if (result && result->connection_state == kCsOffline) {
- if (error_out) *error_out = "device offline";
+ *error_out = "device offline";
result = NULL;
}
/* check for required connection state */
if (result && state != kCsAny && result->connection_state != state) {
- if (error_out) *error_out = "invalid device state";
+ *error_out = "invalid device state";
result = NULL;
}
}
if (result) {
/* found one that we can take */
- if (error_out) *error_out = "success";
+ *error_out = "success";
} else if (state != kCsAny && (serial || !ambiguous)) {
adb_sleep_ms(1000);
goto retry;
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index d3c4c30..97e3d50 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -331,7 +331,11 @@
static void remote_close(atransport *t)
{
- adb_close(t->fd);
+ int fd = t->sfd;
+ if (fd != -1) {
+ t->sfd = -1;
+ adb_close(fd);
+ }
}
diff --git a/debuggerd/Android.mk b/debuggerd/Android.mk
index 6cfb541..3fca709 100644
--- a/debuggerd/Android.mk
+++ b/debuggerd/Android.mk
@@ -77,12 +77,12 @@
debuggerd_test_src_files := \
utility.cpp \
- test/dump_maps_test.cpp \
test/dump_memory_test.cpp \
test/elf_fake.cpp \
test/log_fake.cpp \
test/property_fake.cpp \
test/ptrace_fake.cpp \
+ test/tombstone_test.cpp \
test/selinux_fake.cpp \
debuggerd_shared_libraries := \
diff --git a/debuggerd/arm/machine.cpp b/debuggerd/arm/machine.cpp
index b7d6997..78c2306 100644
--- a/debuggerd/arm/machine.cpp
+++ b/debuggerd/arm/machine.cpp
@@ -15,12 +15,15 @@
* limitations under the License.
*/
+#define LOG_TAG "DEBUG"
+
#include <errno.h>
#include <stdint.h>
#include <string.h>
#include <sys/ptrace.h>
#include <backtrace/Backtrace.h>
+#include <log/log.h>
#include "machine.h"
#include "utility.h"
@@ -28,7 +31,7 @@
void dump_memory_and_code(log_t* log, Backtrace* backtrace) {
pt_regs regs;
if (ptrace(PTRACE_GETREGS, backtrace->Tid(), 0, ®s)) {
- _LOG(log, logtype::ERROR, "cannot get registers: %s\n", strerror(errno));
+ ALOGE("cannot get registers: %s\n", strerror(errno));
return;
}
@@ -48,7 +51,7 @@
void dump_registers(log_t* log, pid_t tid) {
pt_regs r;
if (ptrace(PTRACE_GETREGS, tid, 0, &r)) {
- _LOG(log, logtype::ERROR, "cannot get registers: %s\n", strerror(errno));
+ ALOGE("cannot get registers: %s\n", strerror(errno));
return;
}
@@ -68,7 +71,7 @@
user_vfp vfp_regs;
if (ptrace(PTRACE_GETVFPREGS, tid, 0, &vfp_regs)) {
- _LOG(log, logtype::ERROR, "cannot get FP registers: %s\n", strerror(errno));
+ ALOGE("cannot get FP registers: %s\n", strerror(errno));
return;
}
diff --git a/debuggerd/arm64/machine.cpp b/debuggerd/arm64/machine.cpp
index 2e097da..e7bf79a 100644
--- a/debuggerd/arm64/machine.cpp
+++ b/debuggerd/arm64/machine.cpp
@@ -15,6 +15,8 @@
* limitations under the License.
*/
+#define LOG_TAG "DEBUG"
+
#include <elf.h>
#include <errno.h>
#include <stdint.h>
@@ -23,6 +25,7 @@
#include <sys/uio.h>
#include <backtrace/Backtrace.h>
+#include <log/log.h>
#include "machine.h"
#include "utility.h"
@@ -34,8 +37,7 @@
io.iov_len = sizeof(regs);
if (ptrace(PTRACE_GETREGSET, backtrace->Tid(), reinterpret_cast<void*>(NT_PRSTATUS), &io) == -1) {
- _LOG(log, logtype::ERROR, "%s: ptrace failed to get registers: %s",
- __func__, strerror(errno));
+ ALOGE("ptrace failed to get registers: %s", strerror(errno));
return;
}
@@ -57,7 +59,7 @@
io.iov_len = sizeof(r);
if (ptrace(PTRACE_GETREGSET, tid, (void*) NT_PRSTATUS, (void*) &io) == -1) {
- _LOG(log, logtype::ERROR, "ptrace error: %s\n", strerror(errno));
+ ALOGE("ptrace error: %s\n", strerror(errno));
return;
}
@@ -81,7 +83,7 @@
io.iov_len = sizeof(f);
if (ptrace(PTRACE_GETREGSET, tid, (void*) NT_PRFPREG, (void*) &io) == -1) {
- _LOG(log, logtype::ERROR, "ptrace error: %s\n", strerror(errno));
+ ALOGE("ptrace error: %s\n", strerror(errno));
return;
}
diff --git a/debuggerd/backtrace.cpp b/debuggerd/backtrace.cpp
index b8084c5..b46f8f4 100644
--- a/debuggerd/backtrace.cpp
+++ b/debuggerd/backtrace.cpp
@@ -105,7 +105,7 @@
}
if (!attached && ptrace(PTRACE_DETACH, tid, 0, 0) != 0) {
- _LOG(log, logtype::ERROR, "ptrace detach from %d failed: %s\n", tid, strerror(errno));
+ ALOGE("ptrace detach from %d failed: %s\n", tid, strerror(errno));
*detach_failed = true;
}
}
diff --git a/debuggerd/debuggerd.cpp b/debuggerd/debuggerd.cpp
index 26d6389..787b7aa 100644
--- a/debuggerd/debuggerd.cpp
+++ b/debuggerd/debuggerd.cpp
@@ -63,32 +63,18 @@
int32_t original_si_code;
};
-static void wait_for_user_action(const debugger_request_t &request) {
- // Find out the name of the process that crashed.
- char path[64];
- snprintf(path, sizeof(path), "/proc/%d/exe", request.pid);
-
- char exe[PATH_MAX];
- int count;
- if ((count = readlink(path, exe, sizeof(exe) - 1)) == -1) {
- ALOGE("readlink('%s') failed: %s", path, strerror(errno));
- strlcpy(exe, "unknown", sizeof(exe));
- } else {
- exe[count] = '\0';
- }
-
+static void wait_for_user_action(const debugger_request_t& request) {
// Explain how to attach the debugger.
- ALOGI("********************************************************\n"
+ ALOGI("***********************************************************\n"
"* Process %d has been suspended while crashing.\n"
- "* To attach gdbserver for a gdb connection on port 5039\n"
- "* and start gdbclient:\n"
+ "* To attach gdbserver and start gdb, run this on the host:\n"
"*\n"
- "* gdbclient %s :5039 %d\n"
+ "* gdbclient %d\n"
"*\n"
"* Wait for gdb to start, then press the VOLUME DOWN key\n"
"* to let the process continue crashing.\n"
- "********************************************************",
- request.pid, exe, request.tid);
+ "***********************************************************",
+ request.pid, request.tid);
// Wait for VOLUME DOWN.
if (init_getevent() == 0) {
@@ -250,10 +236,7 @@
static bool should_attach_gdb(debugger_request_t* request) {
if (request->action == DEBUGGER_ACTION_CRASH) {
- char value[PROPERTY_VALUE_MAX];
- property_get("debug.db.uid", value, "-1");
- int debug_uid = atoi(value);
- return debug_uid >= 0 && request->uid <= (uid_t)debug_uid;
+ return property_get_bool("debug.debuggerd.wait_for_gdb", false);
}
return false;
}
diff --git a/debuggerd/mips/machine.cpp b/debuggerd/mips/machine.cpp
index f7b8a86..cbf272a 100644
--- a/debuggerd/mips/machine.cpp
+++ b/debuggerd/mips/machine.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define LOG_TAG "DEBUG"
+
#include <errno.h>
#include <inttypes.h>
#include <stdint.h>
@@ -21,6 +23,7 @@
#include <sys/ptrace.h>
#include <backtrace/Backtrace.h>
+#include <log/log.h>
#include "machine.h"
#include "utility.h"
@@ -32,7 +35,7 @@
void dump_memory_and_code(log_t* log, Backtrace* backtrace) {
pt_regs r;
if (ptrace(PTRACE_GETREGS, backtrace->Tid(), 0, &r)) {
- _LOG(log, logtype::ERROR, "cannot get registers: %s\n", strerror(errno));
+ ALOGE("cannot get registers: %s\n", strerror(errno));
return;
}
@@ -61,7 +64,7 @@
void dump_registers(log_t* log, pid_t tid) {
pt_regs r;
if(ptrace(PTRACE_GETREGS, tid, 0, &r)) {
- _LOG(log, logtype::ERROR, "cannot get registers: %s\n", strerror(errno));
+ ALOGE("cannot get registers: %s\n", strerror(errno));
return;
}
diff --git a/debuggerd/mips64/machine.cpp b/debuggerd/mips64/machine.cpp
index 293dcf6..0a8d532 100644
--- a/debuggerd/mips64/machine.cpp
+++ b/debuggerd/mips64/machine.cpp
@@ -14,6 +14,8 @@
* limitations under the License.
*/
+#define LOG_TAG "DEBUG"
+
#include <errno.h>
#include <inttypes.h>
#include <stdint.h>
@@ -21,6 +23,7 @@
#include <sys/ptrace.h>
#include <backtrace/Backtrace.h>
+#include <log/log.h>
#include "machine.h"
#include "utility.h"
@@ -32,7 +35,7 @@
void dump_memory_and_code(log_t* log, Backtrace* backtrace) {
pt_regs r;
if (ptrace(PTRACE_GETREGS, backtrace->Tid(), 0, &r)) {
- _LOG(log, logtype::ERROR, "cannot get registers: %s\n", strerror(errno));
+ ALOGE("cannot get registers: %s\n", strerror(errno));
return;
}
@@ -61,7 +64,7 @@
void dump_registers(log_t* log, pid_t tid) {
pt_regs r;
if(ptrace(PTRACE_GETREGS, tid, 0, &r)) {
- _LOG(log, logtype::ERROR, "cannot get registers: %s\n", strerror(errno));
+ ALOGE("cannot get registers: %s\n", strerror(errno));
return;
}
diff --git a/debuggerd/test/BacktraceMock.h b/debuggerd/test/BacktraceMock.h
index 5c252ab..f75534e 100644
--- a/debuggerd/test/BacktraceMock.h
+++ b/debuggerd/test/BacktraceMock.h
@@ -60,12 +60,14 @@
}
size_t bytes_available = buffer_.size() - offset;
- if (bytes_partial_read_ > 0) {
+ if (do_partial_read_) {
// Do a partial read.
if (bytes > bytes_partial_read_) {
bytes = bytes_partial_read_;
}
bytes_partial_read_ -= bytes;
+ // Only support a single partial read.
+ do_partial_read_ = false;
} else if (bytes > bytes_available) {
bytes = bytes_available;
}
@@ -82,6 +84,7 @@
buffer_.resize(bytes);
memcpy(buffer_.data(), buffer, bytes);
bytes_partial_read_ = 0;
+ do_partial_read_ = false;
last_read_addr_ = 0;
}
@@ -90,12 +93,14 @@
abort();
}
bytes_partial_read_ = bytes;
+ do_partial_read_ = true;
}
private:
std::vector<uint8_t> buffer_;
size_t bytes_partial_read_ = 0;
uintptr_t last_read_addr_ = 0;
+ bool do_partial_read_ = false;
};
#endif // _DEBUGGERD_TEST_BACKTRACE_MOCK_H
diff --git a/debuggerd/test/dump_memory_test.cpp b/debuggerd/test/dump_memory_test.cpp
index fcb0108..75e7028 100644
--- a/debuggerd/test/dump_memory_test.cpp
+++ b/debuggerd/test/dump_memory_test.cpp
@@ -288,9 +288,9 @@
ASSERT_STREQ(g_expected_partial_dump, tombstone_contents.c_str());
#if defined(__LP64__)
- ASSERT_STREQ("DEBUG Bytes read 102, is not a multiple of 8\n", getFakeLogPrint().c_str());
+ ASSERT_STREQ("6 DEBUG Bytes read 102, is not a multiple of 8\n", getFakeLogPrint().c_str());
#else
- ASSERT_STREQ("DEBUG Bytes read 102, is not a multiple of 4\n", getFakeLogPrint().c_str());
+ ASSERT_STREQ("6 DEBUG Bytes read 102, is not a multiple of 4\n", getFakeLogPrint().c_str());
#endif
// Verify that the log buf is empty, and no error messages.
@@ -313,12 +313,12 @@
ASSERT_STREQ(g_expected_partial_dump, tombstone_contents.c_str());
#if defined(__LP64__)
- ASSERT_STREQ("DEBUG Bytes read 45, is not a multiple of 8\n"
- "DEBUG Bytes after second read 106, is not a multiple of 8\n",
+ ASSERT_STREQ("6 DEBUG Bytes read 45, is not a multiple of 8\n"
+ "6 DEBUG Bytes after second read 106, is not a multiple of 8\n",
getFakeLogPrint().c_str());
#else
- ASSERT_STREQ("DEBUG Bytes read 45, is not a multiple of 4\n"
- "DEBUG Bytes after second read 106, is not a multiple of 4\n",
+ ASSERT_STREQ("6 DEBUG Bytes read 45, is not a multiple of 4\n"
+ "6 DEBUG Bytes after second read 106, is not a multiple of 4\n",
getFakeLogPrint().c_str());
#endif
@@ -502,3 +502,239 @@
ASSERT_STREQ("", getFakeLogBuf().c_str());
ASSERT_STREQ("", getFakeLogPrint().c_str());
}
+
+TEST_F(DumpMemoryTest, first_read_empty) {
+ uint8_t buffer[256];
+ for (size_t i = 0; i < sizeof(buffer); i++) {
+ buffer[i] = i;
+ }
+ backtrace_mock_->SetReadData(buffer, sizeof(buffer));
+ backtrace_mock_->SetPartialReadAmount(0);
+
+ size_t page_size = sysconf(_SC_PAGE_SIZE);
+ uintptr_t addr = 0x10000020 + page_size - 120;
+ dump_memory(&log_, backtrace_mock_.get(), addr, "memory near %.2s:", "r4");
+
+ std::string tombstone_contents;
+ ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
+ ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
+ const char* expected_dump = \
+"\nmemory near r4:\n"
+#if defined(__LP64__)
+" 0000000010000f88 ---------------- ---------------- ................\n"
+" 0000000010000f98 ---------------- ---------------- ................\n"
+" 0000000010000fa8 ---------------- ---------------- ................\n"
+" 0000000010000fb8 ---------------- ---------------- ................\n"
+" 0000000010000fc8 ---------------- ---------------- ................\n"
+" 0000000010000fd8 ---------------- ---------------- ................\n"
+" 0000000010000fe8 ---------------- ---------------- ................\n"
+" 0000000010000ff8 ---------------- 7f7e7d7c7b7a7978 ........xyz{|}~.\n"
+" 0000000010001008 8786858483828180 8f8e8d8c8b8a8988 ................\n"
+" 0000000010001018 9796959493929190 9f9e9d9c9b9a9998 ................\n"
+" 0000000010001028 a7a6a5a4a3a2a1a0 afaeadacabaaa9a8 ................\n"
+" 0000000010001038 b7b6b5b4b3b2b1b0 bfbebdbcbbbab9b8 ................\n"
+" 0000000010001048 c7c6c5c4c3c2c1c0 cfcecdcccbcac9c8 ................\n"
+" 0000000010001058 d7d6d5d4d3d2d1d0 dfdedddcdbdad9d8 ................\n"
+" 0000000010001068 e7e6e5e4e3e2e1e0 efeeedecebeae9e8 ................\n"
+" 0000000010001078 f7f6f5f4f3f2f1f0 fffefdfcfbfaf9f8 ................\n";
+#else
+" 10000f88 -------- -------- -------- -------- ................\n"
+" 10000f98 -------- -------- -------- -------- ................\n"
+" 10000fa8 -------- -------- -------- -------- ................\n"
+" 10000fb8 -------- -------- -------- -------- ................\n"
+" 10000fc8 -------- -------- -------- -------- ................\n"
+" 10000fd8 -------- -------- -------- -------- ................\n"
+" 10000fe8 -------- -------- -------- -------- ................\n"
+" 10000ff8 -------- -------- 7b7a7978 7f7e7d7c ........xyz{|}~.\n"
+" 10001008 83828180 87868584 8b8a8988 8f8e8d8c ................\n"
+" 10001018 93929190 97969594 9b9a9998 9f9e9d9c ................\n"
+" 10001028 a3a2a1a0 a7a6a5a4 abaaa9a8 afaeadac ................\n"
+" 10001038 b3b2b1b0 b7b6b5b4 bbbab9b8 bfbebdbc ................\n"
+" 10001048 c3c2c1c0 c7c6c5c4 cbcac9c8 cfcecdcc ................\n"
+" 10001058 d3d2d1d0 d7d6d5d4 dbdad9d8 dfdedddc ................\n"
+" 10001068 e3e2e1e0 e7e6e5e4 ebeae9e8 efeeedec ................\n"
+" 10001078 f3f2f1f0 f7f6f5f4 fbfaf9f8 fffefdfc ................\n";
+#endif
+ ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
+
+ // Verify that the log buf is empty, and no error messages.
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(DumpMemoryTest, first_read_empty_second_read_stops) {
+ uint8_t buffer[224];
+ for (size_t i = 0; i < sizeof(buffer); i++) {
+ buffer[i] = i;
+ }
+ backtrace_mock_->SetReadData(buffer, sizeof(buffer));
+ backtrace_mock_->SetPartialReadAmount(0);
+
+ size_t page_size = sysconf(_SC_PAGE_SIZE);
+ uintptr_t addr = 0x10000020 + page_size - 192;
+ dump_memory(&log_, backtrace_mock_.get(), addr, "memory near %.2s:", "r4");
+
+ std::string tombstone_contents;
+ ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
+ ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
+ const char* expected_dump = \
+"\nmemory near r4:\n"
+#if defined(__LP64__)
+" 0000000010000f40 ---------------- ---------------- ................\n"
+" 0000000010000f50 ---------------- ---------------- ................\n"
+" 0000000010000f60 ---------------- ---------------- ................\n"
+" 0000000010000f70 ---------------- ---------------- ................\n"
+" 0000000010000f80 ---------------- ---------------- ................\n"
+" 0000000010000f90 ---------------- ---------------- ................\n"
+" 0000000010000fa0 ---------------- ---------------- ................\n"
+" 0000000010000fb0 ---------------- ---------------- ................\n"
+" 0000000010000fc0 ---------------- ---------------- ................\n"
+" 0000000010000fd0 ---------------- ---------------- ................\n"
+" 0000000010000fe0 ---------------- ---------------- ................\n"
+" 0000000010000ff0 ---------------- ---------------- ................\n"
+" 0000000010001000 c7c6c5c4c3c2c1c0 cfcecdcccbcac9c8 ................\n"
+" 0000000010001010 d7d6d5d4d3d2d1d0 dfdedddcdbdad9d8 ................\n"
+" 0000000010001020 ---------------- ---------------- ................\n"
+" 0000000010001030 ---------------- ---------------- ................\n";
+#else
+" 10000f40 -------- -------- -------- -------- ................\n"
+" 10000f50 -------- -------- -------- -------- ................\n"
+" 10000f60 -------- -------- -------- -------- ................\n"
+" 10000f70 -------- -------- -------- -------- ................\n"
+" 10000f80 -------- -------- -------- -------- ................\n"
+" 10000f90 -------- -------- -------- -------- ................\n"
+" 10000fa0 -------- -------- -------- -------- ................\n"
+" 10000fb0 -------- -------- -------- -------- ................\n"
+" 10000fc0 -------- -------- -------- -------- ................\n"
+" 10000fd0 -------- -------- -------- -------- ................\n"
+" 10000fe0 -------- -------- -------- -------- ................\n"
+" 10000ff0 -------- -------- -------- -------- ................\n"
+" 10001000 c3c2c1c0 c7c6c5c4 cbcac9c8 cfcecdcc ................\n"
+" 10001010 d3d2d1d0 d7d6d5d4 dbdad9d8 dfdedddc ................\n"
+" 10001020 -------- -------- -------- -------- ................\n"
+" 10001030 -------- -------- -------- -------- ................\n";
+#endif
+ ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
+
+ // Verify that the log buf is empty, and no error messages.
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(DumpMemoryTest, first_read_empty_next_page_out_of_range) {
+ uint8_t buffer[256];
+ for (size_t i = 0; i < sizeof(buffer); i++) {
+ buffer[i] = i;
+ }
+ backtrace_mock_->SetReadData(buffer, sizeof(buffer));
+ backtrace_mock_->SetPartialReadAmount(0);
+
+ uintptr_t addr = 0x10000020;
+ dump_memory(&log_, backtrace_mock_.get(), addr, "memory near %.2s:", "r4");
+
+ std::string tombstone_contents;
+ ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
+ ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
+ const char* expected_dump = \
+"\nmemory near r4:\n"
+#if defined(__LP64__)
+" 0000000010000000 ---------------- ---------------- ................\n"
+" 0000000010000010 ---------------- ---------------- ................\n"
+" 0000000010000020 ---------------- ---------------- ................\n"
+" 0000000010000030 ---------------- ---------------- ................\n"
+" 0000000010000040 ---------------- ---------------- ................\n"
+" 0000000010000050 ---------------- ---------------- ................\n"
+" 0000000010000060 ---------------- ---------------- ................\n"
+" 0000000010000070 ---------------- ---------------- ................\n"
+" 0000000010000080 ---------------- ---------------- ................\n"
+" 0000000010000090 ---------------- ---------------- ................\n"
+" 00000000100000a0 ---------------- ---------------- ................\n"
+" 00000000100000b0 ---------------- ---------------- ................\n"
+" 00000000100000c0 ---------------- ---------------- ................\n"
+" 00000000100000d0 ---------------- ---------------- ................\n"
+" 00000000100000e0 ---------------- ---------------- ................\n"
+" 00000000100000f0 ---------------- ---------------- ................\n";
+#else
+" 10000000 -------- -------- -------- -------- ................\n"
+" 10000010 -------- -------- -------- -------- ................\n"
+" 10000020 -------- -------- -------- -------- ................\n"
+" 10000030 -------- -------- -------- -------- ................\n"
+" 10000040 -------- -------- -------- -------- ................\n"
+" 10000050 -------- -------- -------- -------- ................\n"
+" 10000060 -------- -------- -------- -------- ................\n"
+" 10000070 -------- -------- -------- -------- ................\n"
+" 10000080 -------- -------- -------- -------- ................\n"
+" 10000090 -------- -------- -------- -------- ................\n"
+" 100000a0 -------- -------- -------- -------- ................\n"
+" 100000b0 -------- -------- -------- -------- ................\n"
+" 100000c0 -------- -------- -------- -------- ................\n"
+" 100000d0 -------- -------- -------- -------- ................\n"
+" 100000e0 -------- -------- -------- -------- ................\n"
+" 100000f0 -------- -------- -------- -------- ................\n";
+#endif
+ ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
+
+ // Verify that the log buf is empty, and no error messages.
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
+
+TEST_F(DumpMemoryTest, first_read_empty_next_page_out_of_range_fence_post) {
+ uint8_t buffer[256];
+ for (size_t i = 0; i < sizeof(buffer); i++) {
+ buffer[i] = i;
+ }
+ backtrace_mock_->SetReadData(buffer, sizeof(buffer));
+ backtrace_mock_->SetPartialReadAmount(0);
+
+ size_t page_size = sysconf(_SC_PAGE_SIZE);
+ uintptr_t addr = 0x10000020 + page_size - 256;
+
+ dump_memory(&log_, backtrace_mock_.get(), addr, "memory near %.2s:", "r4");
+
+ std::string tombstone_contents;
+ ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
+ ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
+ const char* expected_dump = \
+"\nmemory near r4:\n"
+#if defined(__LP64__)
+" 0000000010000f00 ---------------- ---------------- ................\n"
+" 0000000010000f10 ---------------- ---------------- ................\n"
+" 0000000010000f20 ---------------- ---------------- ................\n"
+" 0000000010000f30 ---------------- ---------------- ................\n"
+" 0000000010000f40 ---------------- ---------------- ................\n"
+" 0000000010000f50 ---------------- ---------------- ................\n"
+" 0000000010000f60 ---------------- ---------------- ................\n"
+" 0000000010000f70 ---------------- ---------------- ................\n"
+" 0000000010000f80 ---------------- ---------------- ................\n"
+" 0000000010000f90 ---------------- ---------------- ................\n"
+" 0000000010000fa0 ---------------- ---------------- ................\n"
+" 0000000010000fb0 ---------------- ---------------- ................\n"
+" 0000000010000fc0 ---------------- ---------------- ................\n"
+" 0000000010000fd0 ---------------- ---------------- ................\n"
+" 0000000010000fe0 ---------------- ---------------- ................\n"
+" 0000000010000ff0 ---------------- ---------------- ................\n";
+#else
+" 10000f00 -------- -------- -------- -------- ................\n"
+" 10000f10 -------- -------- -------- -------- ................\n"
+" 10000f20 -------- -------- -------- -------- ................\n"
+" 10000f30 -------- -------- -------- -------- ................\n"
+" 10000f40 -------- -------- -------- -------- ................\n"
+" 10000f50 -------- -------- -------- -------- ................\n"
+" 10000f60 -------- -------- -------- -------- ................\n"
+" 10000f70 -------- -------- -------- -------- ................\n"
+" 10000f80 -------- -------- -------- -------- ................\n"
+" 10000f90 -------- -------- -------- -------- ................\n"
+" 10000fa0 -------- -------- -------- -------- ................\n"
+" 10000fb0 -------- -------- -------- -------- ................\n"
+" 10000fc0 -------- -------- -------- -------- ................\n"
+" 10000fd0 -------- -------- -------- -------- ................\n"
+" 10000fe0 -------- -------- -------- -------- ................\n"
+" 10000ff0 -------- -------- -------- -------- ................\n";
+#endif
+ ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
+
+ // Verify that the log buf is empty, and no error messages.
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ ASSERT_STREQ("", getFakeLogPrint().c_str());
+}
diff --git a/debuggerd/test/log_fake.cpp b/debuggerd/test/log_fake.cpp
index 26523ad..d584a5e 100644
--- a/debuggerd/test/log_fake.cpp
+++ b/debuggerd/test/log_fake.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+#include <errno.h>
#include <stdarg.h>
#include <string>
@@ -44,14 +45,16 @@
return g_fake_log_print;
}
-extern "C" int __android_log_buf_write(int, int, const char* tag, const char* msg) {
+extern "C" int __android_log_buf_write(int bufId, int prio, const char* tag, const char* msg) {
+ g_fake_log_buf += std::to_string(bufId) + ' ' + std::to_string(prio) + ' ';
g_fake_log_buf += tag;
g_fake_log_buf += ' ';
g_fake_log_buf += msg;
return 1;
}
-extern "C" int __android_log_print(int, const char* tag, const char* fmt, ...) {
+extern "C" int __android_log_print(int prio, const char* tag, const char* fmt, ...) {
+ g_fake_log_print += std::to_string(prio) + ' ';
g_fake_log_print += tag;
g_fake_log_print += ' ';
@@ -70,6 +73,7 @@
}
extern "C" struct logger_list* android_logger_list_open(log_id_t, int, unsigned int, pid_t) {
+ errno = EACCES;
return nullptr;
}
diff --git a/debuggerd/test/dump_maps_test.cpp b/debuggerd/test/tombstone_test.cpp
similarity index 90%
rename from debuggerd/test/dump_maps_test.cpp
rename to debuggerd/test/tombstone_test.cpp
index 230f4f5..a771a39 100644
--- a/debuggerd/test/dump_maps_test.cpp
+++ b/debuggerd/test/tombstone_test.cpp
@@ -45,7 +45,7 @@
void dump_backtrace_to_log(Backtrace*, log_t*, char const*) {
}
-class DumpMapsTest : public ::testing::Test {
+class TombstoneTest : public ::testing::Test {
protected:
virtual void SetUp() {
map_mock_.reset(new BacktraceMapMock());
@@ -92,7 +92,7 @@
log_t log_;
};
-TEST_F(DumpMapsTest, single_map) {
+TEST_F(TombstoneTest, single_map) {
backtrace_map_t map;
#if defined(__LP64__)
map.start = 0x123456789abcd000UL;
@@ -122,7 +122,7 @@
ASSERT_STREQ("", getFakeLogPrint().c_str());
}
-TEST_F(DumpMapsTest, single_map_elf_build_id) {
+TEST_F(TombstoneTest, single_map_elf_build_id) {
backtrace_map_t map;
#if defined(__LP64__)
map.start = 0x123456789abcd000UL;
@@ -157,7 +157,7 @@
// Even though build id is present, it should not be printed in either of
// these cases.
-TEST_F(DumpMapsTest, single_map_no_build_id) {
+TEST_F(TombstoneTest, single_map_no_build_id) {
backtrace_map_t map;
#if defined(__LP64__)
map.start = 0x123456789abcd000UL;
@@ -194,7 +194,7 @@
ASSERT_STREQ("", getFakeLogPrint().c_str());
}
-TEST_F(DumpMapsTest, multiple_maps) {
+TEST_F(TombstoneTest, multiple_maps) {
backtrace_map_t map;
map.start = 0xa234000;
@@ -256,7 +256,7 @@
ASSERT_STREQ("", getFakeLogPrint().c_str());
}
-TEST_F(DumpMapsTest, multiple_maps_fault_address_before) {
+TEST_F(TombstoneTest, multiple_maps_fault_address_before) {
backtrace_map_t map;
map.start = 0xa434000;
@@ -310,7 +310,7 @@
ASSERT_STREQ("", getFakeLogPrint().c_str());
}
-TEST_F(DumpMapsTest, multiple_maps_fault_address_between) {
+TEST_F(TombstoneTest, multiple_maps_fault_address_between) {
backtrace_map_t map;
map.start = 0xa434000;
@@ -364,7 +364,7 @@
ASSERT_STREQ("", getFakeLogPrint().c_str());
}
-TEST_F(DumpMapsTest, multiple_maps_fault_address_in_map) {
+TEST_F(TombstoneTest, multiple_maps_fault_address_in_map) {
backtrace_map_t map;
map.start = 0xa434000;
@@ -416,7 +416,7 @@
ASSERT_STREQ("", getFakeLogPrint().c_str());
}
-TEST_F(DumpMapsTest, multiple_maps_fault_address_after) {
+TEST_F(TombstoneTest, multiple_maps_fault_address_after) {
backtrace_map_t map;
map.start = 0xa434000;
@@ -474,7 +474,7 @@
ASSERT_STREQ("", getFakeLogPrint().c_str());
}
-TEST_F(DumpMapsTest, multiple_maps_getsiginfo_fail) {
+TEST_F(TombstoneTest, multiple_maps_getsiginfo_fail) {
backtrace_map_t map;
map.start = 0xa434000;
@@ -493,7 +493,6 @@
ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
const char* expected_dump = \
-"Cannot get siginfo for 100: Bad address\n"
"\nmemory map:\n"
#if defined(__LP64__)
" 00000000'0a434000-00000000'0a434fff -w- 1000 1000 (load base 0xd000)\n";
@@ -503,12 +502,11 @@
ASSERT_STREQ(expected_dump, tombstone_contents.c_str());
// Verify that the log buf is empty, and no error messages.
- ASSERT_STREQ("DEBUG Cannot get siginfo for 100: Bad address\n",
- getFakeLogBuf().c_str());
- ASSERT_STREQ("", getFakeLogPrint().c_str());
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ ASSERT_STREQ("6 DEBUG Cannot get siginfo for 100: Bad address\n\n", getFakeLogPrint().c_str());
}
-TEST_F(DumpMapsTest, multiple_maps_check_signal_has_si_addr) {
+TEST_F(TombstoneTest, multiple_maps_check_signal_has_si_addr) {
backtrace_map_t map;
map.start = 0xa434000;
@@ -569,3 +567,33 @@
ASSERT_STREQ("", getFakeLogPrint().c_str());
}
}
+
+TEST_F(TombstoneTest, dump_signal_info_error) {
+ siginfo_t si;
+ si.si_signo = 0;
+ ptrace_set_fake_getsiginfo(si);
+
+ dump_signal_info(&log_, 123, SIGSEGV, 10);
+
+ std::string tombstone_contents;
+ ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
+ ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
+ ASSERT_STREQ("", tombstone_contents.c_str());
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ ASSERT_STREQ("6 DEBUG cannot get siginfo: Bad address\n\n", getFakeLogPrint().c_str());
+}
+
+TEST_F(TombstoneTest, dump_log_file_error) {
+ log_.should_retrieve_logcat = true;
+ dump_log_file(&log_, 123, "/fake/filename", 10);
+
+ std::string tombstone_contents;
+ ASSERT_TRUE(lseek(log_.tfd, 0, SEEK_SET) == 0);
+ ASSERT_TRUE(android::base::ReadFdToString(log_.tfd, &tombstone_contents));
+ ASSERT_STREQ("", tombstone_contents.c_str());
+
+ ASSERT_STREQ("", getFakeLogBuf().c_str());
+ ASSERT_STREQ("6 DEBUG Unable to open /fake/filename: Permission denied\n\n",
+ getFakeLogPrint().c_str());
+}
diff --git a/debuggerd/tombstone.cpp b/debuggerd/tombstone.cpp
index b0ad274..114c7e4 100644
--- a/debuggerd/tombstone.cpp
+++ b/debuggerd/tombstone.cpp
@@ -180,7 +180,7 @@
siginfo_t si;
memset(&si, 0, sizeof(si));
if (ptrace(PTRACE_GETSIGINFO, tid, 0, &si) == -1) {
- _LOG(log, logtype::HEADER, "cannot get siginfo: %s\n", strerror(errno));
+ ALOGE("cannot get siginfo: %s\n", strerror(errno));
return;
}
@@ -338,7 +338,7 @@
print_fault_address_marker = signal_has_si_addr(si.si_signo);
addr = reinterpret_cast<uintptr_t>(si.si_addr);
} else {
- _LOG(log, logtype::ERROR, "Cannot get siginfo for %d: %s\n", tid, strerror(errno));
+ ALOGE("Cannot get siginfo for %d: %s\n", tid, strerror(errno));
}
_LOG(log, logtype::MAPS, "\n");
@@ -448,7 +448,7 @@
// Skip this thread if cannot ptrace it
if (ptrace(PTRACE_ATTACH, new_tid, 0, 0) < 0) {
- _LOG(log, logtype::ERROR, "ptrace attach to %d failed: %s\n", new_tid, strerror(errno));
+ ALOGE("ptrace attach to %d failed: %s\n", new_tid, strerror(errno));
continue;
}
@@ -471,7 +471,7 @@
log->current_tid = log->crashed_tid;
if (ptrace(PTRACE_DETACH, new_tid, 0, 0) != 0) {
- _LOG(log, logtype::ERROR, "ptrace detach from %d failed: %s\n", new_tid, strerror(errno));
+ ALOGE("ptrace detach from %d failed: %s\n", new_tid, strerror(errno));
detach_failed = true;
}
}
@@ -517,13 +517,11 @@
// non-blocking EOF; we're done
break;
} else {
- _LOG(log, logtype::ERROR, "Error while reading log: %s\n",
- strerror(-actual));
+ ALOGE("Error while reading log: %s\n", strerror(-actual));
break;
}
} else if (actual == 0) {
- _LOG(log, logtype::ERROR, "Got zero bytes while reading log: %s\n",
- strerror(errno));
+ ALOGE("Got zero bytes while reading log: %s\n", strerror(errno));
break;
}
@@ -789,11 +787,11 @@
log.crashed_tid = tid;
if ((mkdir(TOMBSTONE_DIR, 0755) == -1) && (errno != EEXIST)) {
- _LOG(&log, logtype::ERROR, "failed to create %s: %s\n", TOMBSTONE_DIR, strerror(errno));
+ ALOGE("failed to create %s: %s\n", TOMBSTONE_DIR, strerror(errno));
}
if (chown(TOMBSTONE_DIR, AID_SYSTEM, AID_SYSTEM) == -1) {
- _LOG(&log, logtype::ERROR, "failed to change ownership of %s: %s\n", TOMBSTONE_DIR, strerror(errno));
+ ALOGE("failed to change ownership of %s: %s\n", TOMBSTONE_DIR, strerror(errno));
}
int fd = -1;
@@ -801,11 +799,11 @@
if (selinux_android_restorecon(TOMBSTONE_DIR, 0) == 0) {
path = find_and_open_tombstone(&fd);
} else {
- _LOG(&log, logtype::ERROR, "Failed to restore security context, not writing tombstone.\n");
+ ALOGE("Failed to restore security context, not writing tombstone.\n");
}
if (fd < 0) {
- _LOG(&log, logtype::ERROR, "Skipping tombstone write, nothing to do.\n");
+ ALOGE("Skipping tombstone write, nothing to do.\n");
*detach_failed = false;
return NULL;
}
diff --git a/debuggerd/utility.cpp b/debuggerd/utility.cpp
index 9f340a8..f5d6ec1 100644
--- a/debuggerd/utility.cpp
+++ b/debuggerd/utility.cpp
@@ -35,8 +35,7 @@
// Whitelist output desired in the logcat output.
bool is_allowed_in_logcat(enum logtype ltype) {
- if ((ltype == ERROR)
- || (ltype == HEADER)
+ if ((ltype == HEADER)
|| (ltype == REGISTERS)
|| (ltype == BACKTRACE)) {
return true;
@@ -157,13 +156,28 @@
bytes &= ~(sizeof(uintptr_t) - 1);
}
- if (bytes < MEMORY_BYTES_TO_DUMP && bytes > 0) {
- // Try to do one more read. This could happen if a read crosses a map, but
- // the maps do not have any break between them. Only requires one extra
- // read because a map has to contain at least one page, and the total
- // number of bytes to dump is smaller than a page.
- size_t bytes2 = backtrace->Read(addr + bytes, reinterpret_cast<uint8_t*>(data) + bytes,
- sizeof(data) - bytes);
+ uintptr_t start = 0;
+ bool skip_2nd_read = false;
+ if (bytes == 0) {
+ // In this case, we might want to try another read at the beginning of
+ // the next page only if it's within the amount of memory we would have
+ // read.
+ size_t page_size = sysconf(_SC_PAGE_SIZE);
+ start = ((addr + (page_size - 1)) & ~(page_size - 1)) - addr;
+ if (start == 0 || start >= MEMORY_BYTES_TO_DUMP) {
+ skip_2nd_read = true;
+ }
+ }
+
+ if (bytes < MEMORY_BYTES_TO_DUMP && !skip_2nd_read) {
+ // Try to do one more read. This could happen if a read crosses a map,
+ // but the maps do not have any break between them. Or it could happen
+ // if reading from an unreadable map, but the read would cross back
+ // into a readable map. Only requires one extra read because a map has
+ // to contain at least one page, and the total number of bytes to dump
+ // is smaller than a page.
+ size_t bytes2 = backtrace->Read(addr + start + bytes, reinterpret_cast<uint8_t*>(data) + bytes,
+ sizeof(data) - bytes - start);
bytes += bytes2;
if (bytes2 > 0 && bytes % sizeof(uintptr_t) != 0) {
// This should never happen, but we'll try and continue any way.
@@ -179,15 +193,16 @@
// On 32-bit machines, there are still 16 bytes per line but addresses and
// words are of course presented differently.
uintptr_t* data_ptr = data;
+ size_t current = 0;
+ size_t total_bytes = start + bytes;
for (size_t line = 0; line < MEMORY_BYTES_TO_DUMP / MEMORY_BYTES_PER_LINE; line++) {
std::string logline;
android::base::StringAppendF(&logline, " %" PRIPTR, addr);
addr += MEMORY_BYTES_PER_LINE;
std::string ascii;
- for (size_t i = 0; i < MEMORY_BYTES_PER_LINE / sizeof(uintptr_t); i++, data_ptr++) {
- if (bytes >= sizeof(uintptr_t)) {
- bytes -= sizeof(uintptr_t);
+ for (size_t i = 0; i < MEMORY_BYTES_PER_LINE / sizeof(uintptr_t); i++) {
+ if (current >= start && current + sizeof(uintptr_t) <= total_bytes) {
android::base::StringAppendF(&logline, " %" PRIPTR, *data_ptr);
// Fill out the ascii string from the data.
@@ -199,10 +214,12 @@
ascii += '.';
}
}
+ data_ptr++;
} else {
logline += ' ' + std::string(sizeof(uintptr_t) * 2, '-');
ascii += std::string(sizeof(uintptr_t), '.');
}
+ current += sizeof(uintptr_t);
}
_LOG(log, logtype::MEMORY, "%s %s\n", logline.c_str(), ascii.c_str());
}
diff --git a/debuggerd/utility.h b/debuggerd/utility.h
index 263374d..8bef192 100644
--- a/debuggerd/utility.h
+++ b/debuggerd/utility.h
@@ -59,7 +59,6 @@
// List of types of logs to simplify the logging decision in _LOG
enum logtype {
- ERROR,
HEADER,
THREAD,
REGISTERS,
diff --git a/debuggerd/x86/machine.cpp b/debuggerd/x86/machine.cpp
index c5f9259..af10817 100644
--- a/debuggerd/x86/machine.cpp
+++ b/debuggerd/x86/machine.cpp
@@ -14,12 +14,15 @@
* limitations under the License.
*/
+#define LOG_TAG "DEBUG"
+
#include <errno.h>
#include <stdint.h>
#include <string.h>
#include <sys/ptrace.h>
#include <backtrace/Backtrace.h>
+#include <log/log.h>
#include "machine.h"
#include "utility.h"
@@ -27,7 +30,7 @@
void dump_memory_and_code(log_t* log, Backtrace* backtrace) {
struct pt_regs r;
if (ptrace(PTRACE_GETREGS, backtrace->Tid(), 0, &r) == -1) {
- _LOG(log, logtype::ERROR, "cannot get registers: %s\n", strerror(errno));
+ ALOGE("cannot get registers: %s\n", strerror(errno));
return;
}
@@ -44,7 +47,7 @@
void dump_registers(log_t* log, pid_t tid) {
struct pt_regs r;
if (ptrace(PTRACE_GETREGS, tid, 0, &r) == -1) {
- _LOG(log, logtype::ERROR, "cannot get registers: %s\n", strerror(errno));
+ ALOGE("cannot get registers: %s\n", strerror(errno));
return;
}
diff --git a/debuggerd/x86_64/machine.cpp b/debuggerd/x86_64/machine.cpp
index 4f09a5d..fc86bc2 100644
--- a/debuggerd/x86_64/machine.cpp
+++ b/debuggerd/x86_64/machine.cpp
@@ -14,6 +14,8 @@
** limitations under the License.
*/
+#define LOG_TAG "DEBUG"
+
#include <errno.h>
#include <stdint.h>
#include <sys/ptrace.h>
@@ -21,6 +23,7 @@
#include <sys/user.h>
#include <backtrace/Backtrace.h>
+#include <log/log.h>
#include "machine.h"
#include "utility.h"
@@ -28,7 +31,7 @@
void dump_memory_and_code(log_t* log, Backtrace* backtrace) {
struct user_regs_struct r;
if (ptrace(PTRACE_GETREGS, backtrace->Tid(), 0, &r) == -1) {
- _LOG(log, logtype::ERROR, "cannot get registers: %s\n", strerror(errno));
+ ALOGE("cannot get registers: %s\n", strerror(errno));
return;
}
@@ -45,7 +48,7 @@
void dump_registers(log_t* log, pid_t tid) {
struct user_regs_struct r;
if (ptrace(PTRACE_GETREGS, tid, 0, &r) == -1) {
- _LOG(log, logtype::ERROR, "cannot get registers: %s\n", strerror(errno));
+ ALOGE("cannot get registers: %s\n", strerror(errno));
return;
}
diff --git a/fastboot/Android.mk b/fastboot/Android.mk
index 66a470a..ce8e15f 100644
--- a/fastboot/Android.mk
+++ b/fastboot/Android.mk
@@ -21,7 +21,7 @@
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../mkbootimg \
$(LOCAL_PATH)/../../extras/ext4_utils \
$(LOCAL_PATH)/../../extras/f2fs_utils
-LOCAL_SRC_FILES := protocol.c engine.c bootimg_utils.cpp fastboot.cpp util.c fs.c
+LOCAL_SRC_FILES := protocol.cpp engine.cpp bootimg_utils.cpp fastboot.cpp util.cpp fs.cpp
LOCAL_MODULE := fastboot
LOCAL_MODULE_TAGS := debug
LOCAL_CONLYFLAGS += -std=gnu99
@@ -30,17 +30,17 @@
LOCAL_CFLAGS += -DFASTBOOT_REVISION='"$(fastboot_version)"'
ifeq ($(HOST_OS),linux)
- LOCAL_SRC_FILES += usb_linux.c util_linux.c
+ LOCAL_SRC_FILES += usb_linux.cpp util_linux.cpp
endif
ifeq ($(HOST_OS),darwin)
- LOCAL_SRC_FILES += usb_osx.c util_osx.c
+ LOCAL_SRC_FILES += usb_osx.cpp util_osx.cpp
LOCAL_LDLIBS += -lpthread -framework CoreFoundation -framework IOKit -framework Carbon
LOCAL_CFLAGS += -Wno-unused-parameter
endif
ifeq ($(HOST_OS),windows)
- LOCAL_SRC_FILES += usb_windows.c util_windows.c
+ LOCAL_SRC_FILES += usb_windows.cpp util_windows.cpp
EXTRA_STATIC_LIBS := AdbWinApi
ifneq ($(strip $(USE_CYGWIN)),)
# Pure cygwin case
@@ -97,10 +97,9 @@
$(call dist-for-goals,dist_files sdk,$(my_dist_files))
my_dist_files :=
-
ifeq ($(HOST_OS),linux)
include $(CLEAR_VARS)
-LOCAL_SRC_FILES := usbtest.c usb_linux.c util.c
+LOCAL_SRC_FILES := usbtest.cpp usb_linux.cpp util.cpp
LOCAL_MODULE := usbtest
LOCAL_CFLAGS := -Werror
include $(BUILD_HOST_EXECUTABLE)
diff --git a/fastboot/engine.c b/fastboot/engine.cpp
similarity index 89%
rename from fastboot/engine.c
rename to fastboot/engine.cpp
index 2f90e41..66b8140 100644
--- a/fastboot/engine.c
+++ b/fastboot/engine.cpp
@@ -45,10 +45,6 @@
#include <sys/mman.h>
#endif
-#ifndef __unused
-#define __unused __attribute__((__unused__))
-#endif
-
#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
#define OP_DOWNLOAD 1
@@ -73,7 +69,7 @@
unsigned size;
const char *msg;
- int (*func)(Action *a, int status, char *resp);
+ int (*func)(Action* a, int status, const char* resp);
double start;
};
@@ -121,8 +117,7 @@
return !!fs_get_generator(fs_type);
}
-static int cb_default(Action *a, int status, char *resp)
-{
+static int cb_default(Action* a, int status, const char* resp) {
if (status) {
fprintf(stderr,"FAILED (%s)\n", resp);
} else {
@@ -135,12 +130,11 @@
static Action *queue_action(unsigned op, const char *fmt, ...)
{
- Action *a;
va_list ap;
size_t cmdsize;
- a = calloc(1, sizeof(Action));
- if (a == 0) die("out of memory");
+ Action* a = reinterpret_cast<Action*>(calloc(1, sizeof(Action)));
+ if (a == nullptr) die("out of memory");
va_start(ap, fmt);
cmdsize = vsnprintf(a->cmd, sizeof(a->cmd), fmt, ap);
@@ -198,8 +192,7 @@
a->msg = mkmsg("writing '%s'", ptn);
}
-static int match(char *str, const char **value, unsigned count)
-{
+static int match(const char* str, const char** value, unsigned count) {
unsigned n;
for (n = 0; n < count; n++) {
@@ -222,9 +215,9 @@
-static int cb_check(Action *a, int status, char *resp, int invert)
+static int cb_check(Action* a, int status, const char* resp, int invert)
{
- const char **value = a->data;
+ const char** value = reinterpret_cast<const char**>(a->data);
unsigned count = a->size;
unsigned n;
int yes;
@@ -265,18 +258,16 @@
return -1;
}
-static int cb_require(Action *a, int status, char *resp)
-{
+static int cb_require(Action*a, int status, const char* resp) {
return cb_check(a, status, resp, 0);
}
-static int cb_reject(Action *a, int status, char *resp)
-{
+static int cb_reject(Action* a, int status, const char* resp) {
return cb_check(a, status, resp, 1);
}
void fb_queue_require(const char *prod, const char *var,
- int invert, unsigned nvalues, const char **value)
+ int invert, unsigned nvalues, const char **value)
{
Action *a;
a = queue_action(OP_QUERY, "getvar:%s", var);
@@ -285,11 +276,10 @@
a->size = nvalues;
a->msg = mkmsg("checking %s", var);
a->func = invert ? cb_reject : cb_require;
- if (a->data == 0) die("out of memory");
+ if (a->data == nullptr) die("out of memory");
}
-static int cb_display(Action *a, int status, char *resp)
-{
+static int cb_display(Action* a, int status, const char* resp) {
if (status) {
fprintf(stderr, "%s FAILED (%s)\n", a->cmd, resp);
return status;
@@ -303,17 +293,16 @@
Action *a;
a = queue_action(OP_QUERY, "getvar:%s", var);
a->data = strdup(prettyname);
- if (a->data == 0) die("out of memory");
+ if (a->data == nullptr) die("out of memory");
a->func = cb_display;
}
-static int cb_save(Action *a, int status, char *resp)
-{
+static int cb_save(Action* a, int status, const char* resp) {
if (status) {
fprintf(stderr, "%s FAILED (%s)\n", a->cmd, resp);
return status;
}
- strncpy(a->data, resp, a->size);
+ strncpy(reinterpret_cast<char*>(a->data), resp, a->size);
return 0;
}
@@ -326,8 +315,7 @@
a->func = cb_save;
}
-static int cb_do_nothing(Action *a __unused, int status __unused, char *resp __unused)
-{
+static int cb_do_nothing(Action*, int , const char*) {
fprintf(stderr,"\n");
return 0;
}
@@ -398,7 +386,7 @@
} else if (a->op == OP_NOTICE) {
fprintf(stderr,"%s\n",(char*)a->data);
} else if (a->op == OP_DOWNLOAD_SPARSE) {
- status = fb_download_data_sparse(usb, a->data);
+ status = fb_download_data_sparse(usb, reinterpret_cast<sparse_file*>(a->data));
status = a->func(a, status, status ? fb_get_error() : "");
if (status) break;
} else if (a->op == OP_WAIT_FOR_DISCONNECT) {
@@ -414,5 +402,5 @@
int fb_queue_is_empty(void)
{
- return (action_list == NULL);
+ return (action_list == nullptr);
}
diff --git a/fastboot/fastboot.cpp b/fastboot/fastboot.cpp
index 4c4c95b..b964a36 100644
--- a/fastboot/fastboot.cpp
+++ b/fastboot/fastboot.cpp
@@ -391,7 +391,7 @@
static void* unzip_file(ZipArchiveHandle zip, const char* entry_name, unsigned* sz)
{
- ZipEntryName zip_entry_name(entry_name);
+ ZipString zip_entry_name(entry_name);
ZipEntry zip_entry;
if (FindEntry(zip, zip_entry_name, &zip_entry) != 0) {
fprintf(stderr, "archive does not contain '%s'\n", entry_name);
@@ -453,7 +453,7 @@
return -1;
}
- ZipEntryName zip_entry_name(entry_name);
+ ZipString zip_entry_name(entry_name);
ZipEntry zip_entry;
if (FindEntry(zip, zip_entry_name, &zip_entry) != 0) {
fprintf(stderr, "archive does not contain '%s'\n", entry_name);
diff --git a/fastboot/fs.c b/fastboot/fs.cpp
similarity index 93%
rename from fastboot/fs.c
rename to fastboot/fs.cpp
index 8a15e6f..d8f9e16 100644
--- a/fastboot/fs.c
+++ b/fastboot/fs.cpp
@@ -38,7 +38,7 @@
static const struct fs_generator {
- char *fs_type; //must match what fastboot reports for partition type
+ const char* fs_type; //must match what fastboot reports for partition type
int (*generate)(int fd, long long partSize); //returns 0 or error value
} generators[] = {
diff --git a/fastboot/protocol.c b/fastboot/protocol.cpp
similarity index 97%
rename from fastboot/protocol.c
rename to fastboot/protocol.cpp
index 5b97600..00c8a03 100644
--- a/fastboot/protocol.c
+++ b/fastboot/protocol.cpp
@@ -223,9 +223,9 @@
static int fb_download_data_sparse_write(void *priv, const void *data, int len)
{
int r;
- usb_handle *usb = priv;
+ usb_handle* usb = reinterpret_cast<usb_handle*>(priv);
int to_write;
- const char *ptr = data;
+ const char* ptr = reinterpret_cast<const char*>(data);
if (usb_buf_len) {
to_write = min(USB_BUF_SIZE - usb_buf_len, len);
diff --git a/fastboot/usb_linux.c b/fastboot/usb_linux.cpp
similarity index 98%
rename from fastboot/usb_linux.c
rename to fastboot/usb_linux.cpp
index 022f364..9078c8f 100644
--- a/fastboot/usb_linux.c
+++ b/fastboot/usb_linux.cpp
@@ -340,7 +340,7 @@
if(filter_usb_device(de->d_name, desc, n, writable, callback,
&in, &out, &ifc) == 0) {
- usb = calloc(1, sizeof(usb_handle));
+ usb = reinterpret_cast<usb_handle*>(calloc(1, sizeof(usb_handle)));
strcpy(usb->fname, devname);
usb->ep_in = in;
usb->ep_out = out;
diff --git a/fastboot/usb_osx.c b/fastboot/usb_osx.cpp
similarity index 98%
rename from fastboot/usb_osx.c
rename to fastboot/usb_osx.cpp
index 0b6c515..a959566 100644
--- a/fastboot/usb_osx.c
+++ b/fastboot/usb_osx.cpp
@@ -26,6 +26,7 @@
* SUCH DAMAGE.
*/
+#include <inttypes.h>
#include <stdio.h>
#include <CoreFoundation/CoreFoundation.h>
#include <IOKit/IOKitLib.h>
@@ -121,7 +122,7 @@
result = (*plugInInterface)->QueryInterface(
plugInInterface,
CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID),
- (LPVOID) &interface);
+ (LPVOID*) &interface);
// No longer need the intermediate plugin
(*plugInInterface)->Release(plugInInterface);
@@ -279,7 +280,7 @@
// Now create the device interface.
result = (*plugin)->QueryInterface(plugin,
- CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID) &dev);
+ CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (LPVOID*) &dev);
if ((result != 0) || (dev == NULL)) {
ERR("Couldn't create a device interface (%08x)\n", (int) result);
goto error;
@@ -432,7 +433,7 @@
}
if (h.success) {
- *handle = calloc(1, sizeof(usb_handle));
+ *handle = reinterpret_cast<usb_handle*>(calloc(1, sizeof(usb_handle)));
memcpy(*handle, &h, sizeof(usb_handle));
ret = 0;
break;
diff --git a/fastboot/usb_windows.c b/fastboot/usb_windows.cpp
similarity index 100%
rename from fastboot/usb_windows.c
rename to fastboot/usb_windows.cpp
diff --git a/fastboot/usbtest.c b/fastboot/usbtest.cpp
similarity index 100%
rename from fastboot/usbtest.c
rename to fastboot/usbtest.cpp
diff --git a/fastboot/util.c b/fastboot/util.cpp
similarity index 100%
rename from fastboot/util.c
rename to fastboot/util.cpp
diff --git a/fastboot/util_linux.c b/fastboot/util_linux.cpp
similarity index 98%
rename from fastboot/util_linux.c
rename to fastboot/util_linux.cpp
index 91c3776..b788199 100644
--- a/fastboot/util_linux.c
+++ b/fastboot/util_linux.cpp
@@ -26,6 +26,8 @@
* SUCH DAMAGE.
*/
+#include "fastboot.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/fastboot/util_osx.c b/fastboot/util_osx.cpp
similarity index 98%
rename from fastboot/util_osx.c
rename to fastboot/util_osx.cpp
index e718562..ae0b024 100644
--- a/fastboot/util_osx.c
+++ b/fastboot/util_osx.cpp
@@ -26,6 +26,8 @@
* SUCH DAMAGE.
*/
+#include "fastboot.h"
+
#import <Carbon/Carbon.h>
#include <unistd.h>
diff --git a/fastboot/util_windows.c b/fastboot/util_windows.cpp
similarity index 98%
rename from fastboot/util_windows.c
rename to fastboot/util_windows.cpp
index 74a5c27..ec52f39 100644
--- a/fastboot/util_windows.c
+++ b/fastboot/util_windows.cpp
@@ -26,6 +26,8 @@
* SUCH DAMAGE.
*/
+#include "fastboot.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
diff --git a/include/ziparchive/zip_archive.h b/include/ziparchive/zip_archive.h
index 386a390..5ef2ab0 100644
--- a/include/ziparchive/zip_archive.h
+++ b/include/ziparchive/zip_archive.h
@@ -33,17 +33,33 @@
kCompressDeflated = 8, // standard deflate
};
-struct ZipEntryName {
+struct ZipString {
const uint8_t* name;
uint16_t name_length;
- ZipEntryName() {}
+ ZipString() {}
/*
* entry_name has to be an c-style string with only ASCII characters.
*/
- explicit ZipEntryName(const char* entry_name)
+ explicit ZipString(const char* entry_name)
: name(reinterpret_cast<const uint8_t*>(entry_name)), name_length(strlen(entry_name)) {}
+
+ bool operator==(const ZipString& rhs) const {
+ return name && (name_length == rhs.name_length) &&
+ (memcmp(name, rhs.name, name_length) == 0);
+ }
+
+ bool StartsWith(const ZipString& prefix) const {
+ return name && (name_length >= prefix.name_length) &&
+ (memcmp(name, prefix.name, prefix.name_length) == 0);
+ }
+
+ bool EndsWith(const ZipString& suffix) const {
+ return name && (name_length >= suffix.name_length) &&
+ (memcmp(name + name_length - suffix.name_length, suffix.name,
+ suffix.name_length) == 0);
+ }
};
/*
@@ -136,7 +152,7 @@
* and length, a call to VerifyCrcAndLengths must be made after entry data
* has been processed.
*/
-int32_t FindEntry(const ZipArchiveHandle handle, const ZipEntryName& entryName,
+int32_t FindEntry(const ZipArchiveHandle handle, const ZipString& entryName,
ZipEntry* data);
/*
@@ -147,13 +163,14 @@
* calls to Next. All calls to StartIteration must be matched by a call to
* EndIteration to free any allocated memory.
*
- * This method also accepts an optional prefix to restrict iteration to
- * entry names that start with |optional_prefix|.
+ * This method also accepts optional prefix and suffix to restrict iteration to
+ * entry names that start with |optional_prefix| or end with |optional_suffix|.
*
* Returns 0 on success and negative values on failure.
*/
int32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr,
- const ZipEntryName* optional_prefix);
+ const ZipString* optional_prefix,
+ const ZipString* optional_suffix);
/*
* Advance to the next element in the zipfile in iteration order.
@@ -161,7 +178,7 @@
* Returns 0 on success, -1 if there are no more elements in this
* archive and lower negative values on failure.
*/
-int32_t Next(void* cookie, ZipEntry* data, ZipEntryName *name);
+int32_t Next(void* cookie, ZipEntry* data, ZipString* name);
/*
* End iteration over all entries of a zip file and frees the memory allocated
diff --git a/libbacktrace/Android.build.mk b/libbacktrace/Android.build.mk
index 35fed6d..4983b55 100644
--- a/libbacktrace/Android.build.mk
+++ b/libbacktrace/Android.build.mk
@@ -20,7 +20,7 @@
LOCAL_MODULE_TAGS := $(module_tag)
LOCAL_MULTILIB := $($(module)_multilib)
ifeq ($(LOCAL_MULTILIB),both)
-ifneq ($(build_target),$(filter $(build_target),SHARED_LIBRARY STATIC_LIBRRARY))
+ifneq ($(build_target),$(filter $(build_target),SHARED_LIBRARY STATIC_LIBRARY))
LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)64
endif
diff --git a/libbacktrace/Android.mk b/libbacktrace/Android.mk
index be8b803..395d677 100644
--- a/libbacktrace/Android.mk
+++ b/libbacktrace/Android.mk
@@ -68,6 +68,14 @@
build_type := host
libbacktrace_multilib := both
include $(LOCAL_PATH)/Android.build.mk
+libbacktrace_static_libraries := \
+ libbase \
+ liblog \
+ libunwind \
+
+build_target := STATIC_LIBRARY
+include $(LOCAL_PATH)/Android.build.mk
+libbacktrace_static_libraries :=
#-------------------------------------------------------------------------
# The libbacktrace_test library needed by backtrace_test.
diff --git a/libbacktrace/backtrace_test.cpp b/libbacktrace/backtrace_test.cpp
index 760f5cc..6bd7529 100644
--- a/libbacktrace/backtrace_test.cpp
+++ b/libbacktrace/backtrace_test.cpp
@@ -974,8 +974,8 @@
<< "Offset at " << i << " length " << j << " wrote too much data";
}
}
- delete data;
- delete expected;
+ delete[] data;
+ delete[] expected;
}
TEST(libbacktrace, thread_read) {
diff --git a/libcutils/fs_config.c b/libcutils/fs_config.c
index 9f8023e..cb77ee6 100644
--- a/libcutils/fs_config.c
+++ b/libcutils/fs_config.c
@@ -76,6 +76,7 @@
static const struct fs_path_config android_dirs[] = {
{ 00770, AID_SYSTEM, AID_CACHE, 0, "cache" },
+ { 00500, AID_ROOT, AID_ROOT, 0, "config" },
{ 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/app" },
{ 00771, AID_SYSTEM, AID_SYSTEM, 0, "data/app-private" },
{ 00771, AID_ROOT, AID_ROOT, 0, "data/dalvik-cache" },
@@ -88,7 +89,10 @@
{ 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media" },
{ 00775, AID_MEDIA_RW, AID_MEDIA_RW, 0, "data/media/Music" },
{ 00771, AID_SYSTEM, AID_SYSTEM, 0, "data" },
+ { 00755, AID_ROOT, AID_SYSTEM, 0, "mnt" },
+ { 00755, AID_ROOT, AID_ROOT, 0, "root" },
{ 00750, AID_ROOT, AID_SHELL, 0, "sbin" },
+ { 00751, AID_ROOT, AID_SDCARD_R, 0, "storage" },
{ 00755, AID_ROOT, AID_SHELL, 0, "system/bin" },
{ 00755, AID_ROOT, AID_SHELL, 0, "system/vendor" },
{ 00755, AID_ROOT, AID_SHELL, 0, "system/xbin" },
diff --git a/libnativebridge/Android.mk b/libnativebridge/Android.mk
index 83169eb..d20d44c 100644
--- a/libnativebridge/Android.mk
+++ b/libnativebridge/Android.mk
@@ -37,4 +37,22 @@
include $(BUILD_HOST_SHARED_LIBRARY)
+# Static library for host
+# ========================================================
+include $(CLEAR_VARS)
+
+LOCAL_MODULE:= libnativebridge
+
+LOCAL_SRC_FILES:= $(NATIVE_BRIDGE_COMMON_SRC_FILES)
+LOCAL_STATIC_LIBRARIES := liblog
+LOCAL_CLANG := true
+LOCAL_CPP_EXTENSION := .cc
+LOCAL_CFLAGS += -Werror -Wall
+LOCAL_CPPFLAGS := -std=gnu++11 -fvisibility=protected
+LOCAL_LDFLAGS := -ldl
+LOCAL_MULTILIB := both
+
+include $(BUILD_HOST_STATIC_LIBRARY)
+
+
include $(LOCAL_PATH)/tests/Android.mk
diff --git a/libnativebridge/native_bridge.cc b/libnativebridge/native_bridge.cc
index f63497b..a9671a9 100644
--- a/libnativebridge/native_bridge.cc
+++ b/libnativebridge/native_bridge.cc
@@ -109,6 +109,13 @@
}
}
+static void ReleaseAppCodeCacheDir() {
+ if (app_code_cache_dir != nullptr) {
+ delete[] app_code_cache_dir;
+ app_code_cache_dir = nullptr;
+ }
+}
+
// We only allow simple names for the library. It is supposed to be a file in
// /system/lib or /vendor/lib. Only allow a small range of characters, that is
// names consisting of [a-zA-Z0-9._-] and starting with [a-zA-Z].
@@ -162,8 +169,7 @@
static void CloseNativeBridge(bool with_error) {
state = NativeBridgeState::kClosed;
had_error |= with_error;
- delete[] app_code_cache_dir;
- app_code_cache_dir = nullptr;
+ ReleaseAppCodeCacheDir();
}
bool LoadNativeBridge(const char* nb_library_filename,
@@ -406,16 +412,16 @@
if (stat(app_code_cache_dir, &st) == -1) {
if (errno == ENOENT) {
if (mkdir(app_code_cache_dir, S_IRWXU | S_IRWXG | S_IXOTH) == -1) {
- ALOGE("Cannot create code cache directory %s: %s.", app_code_cache_dir, strerror(errno));
- CloseNativeBridge(true);
+ ALOGW("Cannot create code cache directory %s: %s.", app_code_cache_dir, strerror(errno));
+ ReleaseAppCodeCacheDir();
}
} else {
- ALOGE("Cannot stat code cache directory %s: %s.", app_code_cache_dir, strerror(errno));
- CloseNativeBridge(true);
+ ALOGW("Cannot stat code cache directory %s: %s.", app_code_cache_dir, strerror(errno));
+ ReleaseAppCodeCacheDir();
}
} else if (!S_ISDIR(st.st_mode)) {
- ALOGE("Code cache is not a directory %s.", app_code_cache_dir);
- CloseNativeBridge(true);
+ ALOGW("Code cache is not a directory %s.", app_code_cache_dir);
+ ReleaseAppCodeCacheDir();
}
// If we're still PreInitialized (dind't fail the code cache checks) try to initialize.
@@ -424,8 +430,7 @@
SetupEnvironment(callbacks, env, instruction_set);
state = NativeBridgeState::kInitialized;
// We no longer need the code cache path, release the memory.
- delete[] app_code_cache_dir;
- app_code_cache_dir = nullptr;
+ ReleaseAppCodeCacheDir();
} else {
// Unload the library.
dlclose(native_bridge_handle);
diff --git a/libnativebridge/tests/Android.mk b/libnativebridge/tests/Android.mk
index 285e8c2..7265939 100644
--- a/libnativebridge/tests/Android.mk
+++ b/libnativebridge/tests/Android.mk
@@ -9,6 +9,7 @@
test_src_files := \
CodeCacheCreate_test.cpp \
CodeCacheExists_test.cpp \
+ CodeCacheStatFail_test.cpp \
CompleteFlow_test.cpp \
InvalidCharsNativeBridge_test.cpp \
NativeBridge2Signal_test.cpp \
diff --git a/libnativebridge/tests/CodeCacheStatFail_test.cpp b/libnativebridge/tests/CodeCacheStatFail_test.cpp
new file mode 100644
index 0000000..4ea519e
--- /dev/null
+++ b/libnativebridge/tests/CodeCacheStatFail_test.cpp
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "NativeBridgeTest.h"
+
+#include <errno.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+namespace android {
+
+// Tests that the bridge is initialized without errors if the code_cache is
+// existed as a file.
+TEST_F(NativeBridgeTest, CodeCacheStatFail) {
+ int fd = creat(kCodeCache, O_RDWR);
+ ASSERT_NE(-1, fd);
+ close(fd);
+
+ struct stat st;
+ ASSERT_EQ(-1, stat(kCodeCacheStatFail, &st));
+ ASSERT_EQ(ENOTDIR, errno);
+
+ // Init
+ ASSERT_TRUE(LoadNativeBridge(kNativeBridgeLibrary, nullptr));
+ ASSERT_TRUE(PreInitializeNativeBridge(kCodeCacheStatFail, "isa"));
+ ASSERT_TRUE(InitializeNativeBridge(nullptr, nullptr));
+ ASSERT_TRUE(NativeBridgeAvailable());
+ ASSERT_FALSE(NativeBridgeError());
+
+ // Clean up
+ UnloadNativeBridge();
+
+ ASSERT_FALSE(NativeBridgeError());
+ unlink(kCodeCache);
+}
+
+} // namespace android
diff --git a/libnativebridge/tests/NativeBridgeTest.h b/libnativebridge/tests/NativeBridgeTest.h
index 6a5c126..d489420 100644
--- a/libnativebridge/tests/NativeBridgeTest.h
+++ b/libnativebridge/tests/NativeBridgeTest.h
@@ -24,6 +24,7 @@
constexpr const char* kNativeBridgeLibrary = "libnativebridge-dummy.so";
constexpr const char* kCodeCache = "./code_cache";
+constexpr const char* kCodeCacheStatFail = "./code_cache/temp";
namespace android {
diff --git a/libsparse/sparse_crc32.h b/libsparse/sparse_crc32.h
index cad8a86..50cd9e9 100644
--- a/libsparse/sparse_crc32.h
+++ b/libsparse/sparse_crc32.h
@@ -14,7 +14,19 @@
* limitations under the License.
*/
+#ifndef _LIBSPARSE_SPARSE_CRC32_H_
+#define _LIBSPARSE_SPARSE_CRC32_H_
+
#include <stdint.h>
+#ifdef __cplusplus
+extern "C" {
+#endif
+
uint32_t sparse_crc32(uint32_t crc, const void *buf, size_t size);
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/libutils/Looper.cpp b/libutils/Looper.cpp
index 9a2dd6c..20c1e92 100644
--- a/libutils/Looper.cpp
+++ b/libutils/Looper.cpp
@@ -17,9 +17,11 @@
#include <utils/Looper.h>
#include <utils/Timers.h>
-#include <unistd.h>
+#include <errno.h>
#include <fcntl.h>
#include <limits.h>
+#include <string.h>
+#include <unistd.h>
namespace android {
@@ -71,32 +73,32 @@
mResponseIndex(0), mNextMessageUptime(LLONG_MAX) {
int wakeFds[2];
int result = pipe(wakeFds);
- LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe. errno=%d", errno);
+ LOG_ALWAYS_FATAL_IF(result != 0, "Could not create wake pipe: %s", strerror(errno));
mWakeReadPipeFd = wakeFds[0];
mWakeWritePipeFd = wakeFds[1];
result = fcntl(mWakeReadPipeFd, F_SETFL, O_NONBLOCK);
- LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking. errno=%d",
- errno);
+ LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake read pipe non-blocking: %s",
+ strerror(errno));
result = fcntl(mWakeWritePipeFd, F_SETFL, O_NONBLOCK);
- LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking. errno=%d",
- errno);
+ LOG_ALWAYS_FATAL_IF(result != 0, "Could not make wake write pipe non-blocking: %s",
+ strerror(errno));
mIdling = false;
// Allocate the epoll instance and register the wake pipe.
mEpollFd = epoll_create(EPOLL_SIZE_HINT);
- LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance. errno=%d", errno);
+ LOG_ALWAYS_FATAL_IF(mEpollFd < 0, "Could not create epoll instance: %s", strerror(errno));
struct epoll_event eventItem;
memset(& eventItem, 0, sizeof(epoll_event)); // zero out unused members of data field union
eventItem.events = EPOLLIN;
eventItem.data.fd = mWakeReadPipeFd;
result = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, mWakeReadPipeFd, & eventItem);
- LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance. errno=%d",
- errno);
+ LOG_ALWAYS_FATAL_IF(result != 0, "Could not add wake read pipe to epoll instance: %s",
+ strerror(errno));
}
Looper::~Looper() {
@@ -233,7 +235,7 @@
if (errno == EINTR) {
goto Done;
}
- ALOGW("Poll failed with an unexpected error, errno=%d", errno);
+ ALOGW("Poll failed with an unexpected error: %s", strerror(errno));
result = POLL_ERROR;
goto Done;
}
@@ -377,7 +379,7 @@
if (nWrite != 1) {
if (errno != EAGAIN) {
- ALOGW("Could not write wake signal, errno=%d", errno);
+ ALOGW("Could not write wake signal: %s", strerror(errno));
}
}
}
@@ -447,14 +449,14 @@
if (requestIndex < 0) {
int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_ADD, fd, & eventItem);
if (epollResult < 0) {
- ALOGE("Error adding epoll events for fd %d, errno=%d", fd, errno);
+ ALOGE("Error adding epoll events for fd %d: %s", fd, strerror(errno));
return -1;
}
mRequests.add(fd, request);
} else {
int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_MOD, fd, & eventItem);
if (epollResult < 0) {
- ALOGE("Error modifying epoll events for fd %d, errno=%d", fd, errno);
+ ALOGE("Error modifying epoll events for fd %d: %s", fd, strerror(errno));
return -1;
}
mRequests.replaceValueAt(requestIndex, request);
@@ -477,7 +479,7 @@
int epollResult = epoll_ctl(mEpollFd, EPOLL_CTL_DEL, fd, NULL);
if (epollResult < 0) {
- ALOGE("Error removing epoll events for fd %d, errno=%d", fd, errno);
+ ALOGE("Error removing epoll events for fd %d: %s", fd, strerror(errno));
return -1;
}
diff --git a/libutils/ProcessCallStack.cpp b/libutils/ProcessCallStack.cpp
index db07e56..011c302 100644
--- a/libutils/ProcessCallStack.cpp
+++ b/libutils/ProcessCallStack.cpp
@@ -17,9 +17,10 @@
#define LOG_TAG "ProcessCallStack"
// #define LOG_NDEBUG 0
-#include <string.h>
-#include <stdio.h>
#include <dirent.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
#include <utils/Log.h>
#include <utils/Errors.h>
@@ -135,8 +136,8 @@
dp = opendir(PATH_SELF_TASK);
if (dp == NULL) {
- ALOGE("%s: Failed to update the process's call stacks (errno = %d, '%s')",
- __FUNCTION__, errno, strerror(errno));
+ ALOGE("%s: Failed to update the process's call stacks: %s",
+ __FUNCTION__, strerror(errno));
return;
}
@@ -172,8 +173,8 @@
ssize_t idx = mThreadMap.add(tid, ThreadInfo());
if (idx < 0) { // returns negative error value on error
- ALOGE("%s: Failed to add new ThreadInfo (errno = %zd, '%s')",
- __FUNCTION__, idx, strerror(-idx));
+ ALOGE("%s: Failed to add new ThreadInfo: %s",
+ __FUNCTION__, strerror(-idx));
continue;
}
@@ -195,8 +196,8 @@
__FUNCTION__, tid, threadInfo.callStack.size());
}
if (code != 0) { // returns positive error value on error
- ALOGE("%s: Failed to readdir from %s (errno = %d, '%s')",
- __FUNCTION__, PATH_SELF_TASK, -code, strerror(code));
+ ALOGE("%s: Failed to readdir from %s: %s",
+ __FUNCTION__, PATH_SELF_TASK, strerror(code));
}
#endif
diff --git a/libutils/SystemClock.cpp b/libutils/SystemClock.cpp
index ac3dd98..64204a8 100644
--- a/libutils/SystemClock.cpp
+++ b/libutils/SystemClock.cpp
@@ -29,7 +29,6 @@
#include <sys/time.h>
#include <limits.h>
#include <fcntl.h>
-#include <errno.h>
#include <string.h>
#include <utils/SystemClock.h>
diff --git a/libutils/Threads.cpp b/libutils/Threads.cpp
index 1e014c6..c3666e4 100644
--- a/libutils/Threads.cpp
+++ b/libutils/Threads.cpp
@@ -22,6 +22,7 @@
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include <unistd.h>
#if !defined(_WIN32)
@@ -160,9 +161,9 @@
(android_pthread_entry)entryFunction, userData);
pthread_attr_destroy(&attr);
if (result != 0) {
- ALOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, errno=%d)\n"
+ ALOGE("androidCreateRawThreadEtc failed (entry=%p, res=%d, %s)\n"
"(android threadPriority=%d)",
- entryFunction, result, errno, threadPriority);
+ entryFunction, result, strerror(errno), threadPriority);
return 0;
}
diff --git a/libutils/Tokenizer.cpp b/libutils/Tokenizer.cpp
index 610002f..2d0e83d 100644
--- a/libutils/Tokenizer.cpp
+++ b/libutils/Tokenizer.cpp
@@ -56,12 +56,12 @@
int fd = ::open(filename.string(), O_RDONLY);
if (fd < 0) {
result = -errno;
- ALOGE("Error opening file '%s', %s.", filename.string(), strerror(errno));
+ ALOGE("Error opening file '%s': %s", filename.string(), strerror(errno));
} else {
struct stat stat;
if (fstat(fd, &stat)) {
result = -errno;
- ALOGE("Error getting size of file '%s', %s.", filename.string(), strerror(errno));
+ ALOGE("Error getting size of file '%s': %s", filename.string(), strerror(errno));
} else {
size_t length = size_t(stat.st_size);
@@ -83,7 +83,7 @@
ssize_t nrd = read(fd, buffer, length);
if (nrd < 0) {
result = -errno;
- ALOGE("Error reading file '%s', %s.", filename.string(), strerror(errno));
+ ALOGE("Error reading file '%s': %s", filename.string(), strerror(errno));
delete[] buffer;
buffer = NULL;
} else {
diff --git a/libutils/misc.cpp b/libutils/misc.cpp
index ed1ba23..216dc14 100644
--- a/libutils/misc.cpp
+++ b/libutils/misc.cpp
@@ -24,7 +24,6 @@
#include <sys/stat.h>
#include <string.h>
-#include <errno.h>
#include <stdio.h>
#if !defined(_WIN32)
diff --git a/libziparchive/Android.mk b/libziparchive/Android.mk
index a3087ee..559c48b 100644
--- a/libziparchive/Android.mk
+++ b/libziparchive/Android.mk
@@ -42,8 +42,8 @@
include $(CLEAR_VARS)
LOCAL_CPP_EXTENSION := .cc
LOCAL_SRC_FILES := ${source_files}
-LOCAL_STATIC_LIBRARIES := libz libutils
-LOCAL_SHARED_LIBRARIES := liblog libbase
+LOCAL_STATIC_LIBRARIES := libutils
+LOCAL_SHARED_LIBRARIES := libz-host liblog libbase
LOCAL_MODULE:= libziparchive-host
LOCAL_CFLAGS := -Werror
LOCAL_MULTILIB := both
diff --git a/libziparchive/zip_archive.cc b/libziparchive/zip_archive.cc
index d7af34e..3716343 100644
--- a/libziparchive/zip_archive.cc
+++ b/libziparchive/zip_archive.cc
@@ -307,7 +307,7 @@
* ((4 * UINT16_MAX) / 3 + 1) which can safely fit into a uint32_t.
*/
uint32_t hash_table_size;
- ZipEntryName* hash_table;
+ ZipString* hash_table;
ZipArchive(const int fd, bool assume_ownership) :
fd(fd),
@@ -343,7 +343,7 @@
return val;
}
-static uint32_t ComputeHash(const ZipEntryName& name) {
+static uint32_t ComputeHash(const ZipString& name) {
uint32_t hash = 0;
uint16_t len = name.name_length;
const uint8_t* str = name.name;
@@ -359,16 +359,15 @@
* Convert a ZipEntry to a hash table index, verifying that it's in a
* valid range.
*/
-static int64_t EntryToIndex(const ZipEntryName* hash_table,
+static int64_t EntryToIndex(const ZipString* hash_table,
const uint32_t hash_table_size,
- const ZipEntryName& name) {
+ const ZipString& name) {
const uint32_t hash = ComputeHash(name);
// NOTE: (hash_table_size - 1) is guaranteed to be non-negative.
uint32_t ent = hash & (hash_table_size - 1);
while (hash_table[ent].name != NULL) {
- if (hash_table[ent].name_length == name.name_length &&
- memcmp(hash_table[ent].name, name.name, name.name_length) == 0) {
+ if (hash_table[ent] == name) {
return ent;
}
@@ -382,8 +381,8 @@
/*
* Add a new entry to the hash table.
*/
-static int32_t AddToHash(ZipEntryName *hash_table, const uint64_t hash_table_size,
- const ZipEntryName& name) {
+static int32_t AddToHash(ZipString *hash_table, const uint64_t hash_table_size,
+ const ZipString& name) {
const uint64_t hash = ComputeHash(name);
uint32_t ent = hash & (hash_table_size - 1);
@@ -392,8 +391,7 @@
* Further, we guarantee that the hashtable size is not 0.
*/
while (hash_table[ent].name != NULL) {
- if (hash_table[ent].name_length == name.name_length &&
- memcmp(hash_table[ent].name, name.name, name.name_length) == 0) {
+ if (hash_table[ent] == name) {
// We've found a duplicate entry. We don't accept it
ALOGW("Zip: Found duplicate entry %.*s", name.name_length, name.name);
return kDuplicateEntry;
@@ -565,8 +563,8 @@
* least one unused entry to avoid an infinite loop during creation.
*/
archive->hash_table_size = RoundUpPower2(1 + (num_entries * 4) / 3);
- archive->hash_table = reinterpret_cast<ZipEntryName*>(calloc(archive->hash_table_size,
- sizeof(ZipEntryName)));
+ archive->hash_table = reinterpret_cast<ZipString*>(calloc(archive->hash_table_size,
+ sizeof(ZipString)));
/*
* Walk through the central directory, adding entries to the hash
@@ -605,7 +603,7 @@
}
/* add the CDE filename to the hash table */
- ZipEntryName entry_name;
+ ZipString entry_name;
entry_name.name = file_name;
entry_name.name_length = file_name_length;
const int add_result = AddToHash(archive->hash_table,
@@ -851,26 +849,41 @@
uint32_t position;
// We're not using vector here because this code is used in the Windows SDK
// where the STL is not available.
- const uint8_t* prefix;
- uint16_t prefix_len;
+ ZipString prefix;
+ ZipString suffix;
ZipArchive* archive;
- IterationHandle() : prefix(NULL), prefix_len(0) {}
-
- IterationHandle(const ZipEntryName& prefix_name)
- : prefix_len(prefix_name.name_length) {
- uint8_t* prefix_copy = new uint8_t[prefix_len];
- memcpy(prefix_copy, prefix_name.name, prefix_len);
- prefix = prefix_copy;
+ IterationHandle(const ZipString* in_prefix,
+ const ZipString* in_suffix) {
+ if (in_prefix) {
+ uint8_t* name_copy = new uint8_t[in_prefix->name_length];
+ memcpy(name_copy, in_prefix->name, in_prefix->name_length);
+ prefix.name = name_copy;
+ prefix.name_length = in_prefix->name_length;
+ } else {
+ prefix.name = NULL;
+ prefix.name_length = 0;
+ }
+ if (in_suffix) {
+ uint8_t* name_copy = new uint8_t[in_suffix->name_length];
+ memcpy(name_copy, in_suffix->name, in_suffix->name_length);
+ suffix.name = name_copy;
+ suffix.name_length = in_suffix->name_length;
+ } else {
+ suffix.name = NULL;
+ suffix.name_length = 0;
+ }
}
~IterationHandle() {
- delete[] prefix;
+ delete[] prefix.name;
+ delete[] suffix.name;
}
};
int32_t StartIteration(ZipArchiveHandle handle, void** cookie_ptr,
- const ZipEntryName* optional_prefix) {
+ const ZipString* optional_prefix,
+ const ZipString* optional_suffix) {
ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle);
if (archive == NULL || archive->hash_table == NULL) {
@@ -878,8 +891,7 @@
return kInvalidHandle;
}
- IterationHandle* cookie =
- optional_prefix != NULL ? new IterationHandle(*optional_prefix) : new IterationHandle();
+ IterationHandle* cookie = new IterationHandle(optional_prefix, optional_suffix);
cookie->position = 0;
cookie->archive = archive;
@@ -891,7 +903,7 @@
delete reinterpret_cast<IterationHandle*>(cookie);
}
-int32_t FindEntry(const ZipArchiveHandle handle, const ZipEntryName& entryName,
+int32_t FindEntry(const ZipArchiveHandle handle, const ZipString& entryName,
ZipEntry* data) {
const ZipArchive* archive = reinterpret_cast<ZipArchive*>(handle);
if (entryName.name_length == 0) {
@@ -910,7 +922,7 @@
return FindEntry(archive, ent, data);
}
-int32_t Next(void* cookie, ZipEntry* data, ZipEntryName* name) {
+int32_t Next(void* cookie, ZipEntry* data, ZipString* name) {
IterationHandle* handle = reinterpret_cast<IterationHandle*>(cookie);
if (handle == NULL) {
return kInvalidHandle;
@@ -924,12 +936,14 @@
const uint32_t currentOffset = handle->position;
const uint32_t hash_table_length = archive->hash_table_size;
- const ZipEntryName *hash_table = archive->hash_table;
+ const ZipString* hash_table = archive->hash_table;
for (uint32_t i = currentOffset; i < hash_table_length; ++i) {
if (hash_table[i].name != NULL &&
- (handle->prefix_len == 0 ||
- (memcmp(handle->prefix, hash_table[i].name, handle->prefix_len) == 0))) {
+ (handle->prefix.name_length == 0 ||
+ hash_table[i].StartsWith(handle->prefix)) &&
+ (handle->suffix.name_length == 0 ||
+ hash_table[i].EndsWith(handle->suffix))) {
handle->position = (i + 1);
const int error = FindEntry(archive, i, data);
if (!error) {
@@ -1265,4 +1279,3 @@
int GetFileDescriptor(const ZipArchiveHandle handle) {
return reinterpret_cast<ZipArchive*>(handle)->fd;
}
-
diff --git a/libziparchive/zip_archive_test.cc b/libziparchive/zip_archive_test.cc
index f8952ce..9a3cdb4 100644
--- a/libziparchive/zip_archive_test.cc
+++ b/libziparchive/zip_archive_test.cc
@@ -70,7 +70,7 @@
}
static void AssertNameEquals(const std::string& name_str,
- const ZipEntryName& name) {
+ const ZipString& name) {
ASSERT_EQ(name_str.size(), name.name_length);
ASSERT_EQ(0, memcmp(name_str.c_str(), name.name, name.name_length));
}
@@ -115,10 +115,10 @@
ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
void* iteration_cookie;
- ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, NULL));
+ ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, NULL, NULL));
ZipEntry data;
- ZipEntryName name;
+ ZipString name;
// b/c.txt
ASSERT_EQ(0, Next(iteration_cookie, &data, &name));
@@ -146,12 +146,122 @@
CloseArchive(handle);
}
+TEST(ziparchive, IterationWithPrefix) {
+ ZipArchiveHandle handle;
+ ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
+
+ void* iteration_cookie;
+ ZipString prefix("b/");
+ ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, &prefix, NULL));
+
+ ZipEntry data;
+ ZipString name;
+
+ // b/c.txt
+ ASSERT_EQ(0, Next(iteration_cookie, &data, &name));
+ AssertNameEquals("b/c.txt", name);
+
+ // b/d.txt
+ ASSERT_EQ(0, Next(iteration_cookie, &data, &name));
+ AssertNameEquals("b/d.txt", name);
+
+ // b/
+ ASSERT_EQ(0, Next(iteration_cookie, &data, &name));
+ AssertNameEquals("b/", name);
+
+ // End of iteration.
+ ASSERT_EQ(-1, Next(iteration_cookie, &data, &name));
+
+ CloseArchive(handle);
+}
+
+TEST(ziparchive, IterationWithSuffix) {
+ ZipArchiveHandle handle;
+ ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
+
+ void* iteration_cookie;
+ ZipString suffix(".txt");
+ ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, NULL, &suffix));
+
+ ZipEntry data;
+ ZipString name;
+
+ // b/c.txt
+ ASSERT_EQ(0, Next(iteration_cookie, &data, &name));
+ AssertNameEquals("b/c.txt", name);
+
+ // b/d.txt
+ ASSERT_EQ(0, Next(iteration_cookie, &data, &name));
+ AssertNameEquals("b/d.txt", name);
+
+ // a.txt
+ ASSERT_EQ(0, Next(iteration_cookie, &data, &name));
+ AssertNameEquals("a.txt", name);
+
+ // b.txt
+ ASSERT_EQ(0, Next(iteration_cookie, &data, &name));
+ AssertNameEquals("b.txt", name);
+
+ // End of iteration.
+ ASSERT_EQ(-1, Next(iteration_cookie, &data, &name));
+
+ CloseArchive(handle);
+}
+
+TEST(ziparchive, IterationWithPrefixAndSuffix) {
+ ZipArchiveHandle handle;
+ ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
+
+ void* iteration_cookie;
+ ZipString prefix("b");
+ ZipString suffix(".txt");
+ ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, &prefix, &suffix));
+
+ ZipEntry data;
+ ZipString name;
+
+ // b/c.txt
+ ASSERT_EQ(0, Next(iteration_cookie, &data, &name));
+ AssertNameEquals("b/c.txt", name);
+
+ // b/d.txt
+ ASSERT_EQ(0, Next(iteration_cookie, &data, &name));
+ AssertNameEquals("b/d.txt", name);
+
+ // b.txt
+ ASSERT_EQ(0, Next(iteration_cookie, &data, &name));
+ AssertNameEquals("b.txt", name);
+
+ // End of iteration.
+ ASSERT_EQ(-1, Next(iteration_cookie, &data, &name));
+
+ CloseArchive(handle);
+}
+
+TEST(ziparchive, IterationWithBadPrefixAndSuffix) {
+ ZipArchiveHandle handle;
+ ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
+
+ void* iteration_cookie;
+ ZipString prefix("x");
+ ZipString suffix("y");
+ ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, &prefix, &suffix));
+
+ ZipEntry data;
+ ZipString name;
+
+ // End of iteration.
+ ASSERT_EQ(-1, Next(iteration_cookie, &data, &name));
+
+ CloseArchive(handle);
+}
+
TEST(ziparchive, FindEntry) {
ZipArchiveHandle handle;
ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
ZipEntry data;
- ZipEntryName name;
+ ZipString name;
name.name = kATxtName;
name.name_length = kATxtNameLength;
ASSERT_EQ(0, FindEntry(handle, name, &data));
@@ -164,7 +274,7 @@
ASSERT_EQ(0x950821c5, data.crc32);
// An entry that doesn't exist. Should be a negative return code.
- ZipEntryName absent_name;
+ ZipString absent_name;
absent_name.name = kNonexistentTxtName;
absent_name.name_length = kNonexistentTxtNameLength;
ASSERT_LT(FindEntry(handle, absent_name, &data), 0);
@@ -177,9 +287,9 @@
ASSERT_EQ(0, OpenArchiveWrapper("declaredlength.zip", &handle));
void* iteration_cookie;
- ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, NULL));
+ ASSERT_EQ(0, StartIteration(handle, &iteration_cookie, NULL, NULL));
- ZipEntryName name;
+ ZipString name;
ZipEntry data;
ASSERT_EQ(Next(iteration_cookie, &data, &name), 0);
@@ -194,7 +304,7 @@
// An entry that's deflated.
ZipEntry data;
- ZipEntryName a_name;
+ ZipString a_name;
a_name.name = kATxtName;
a_name.name_length = kATxtNameLength;
ASSERT_EQ(0, FindEntry(handle, a_name, &data));
@@ -206,7 +316,7 @@
delete[] buffer;
// An entry that's stored.
- ZipEntryName b_name;
+ ZipString b_name;
b_name.name = kBTxtName;
b_name.name_length = kBTxtNameLength;
ASSERT_EQ(0, FindEntry(handle, b_name, &data));
@@ -293,7 +403,7 @@
ASSERT_EQ(0, OpenArchiveFd(fd, "EmptyEntriesTest", &handle));
ZipEntry entry;
- ZipEntryName empty_name;
+ ZipString empty_name;
empty_name.name = kEmptyTxtName;
empty_name.name_length = kEmptyTxtNameLength;
ASSERT_EQ(0, FindEntry(handle, empty_name, &entry));
@@ -324,7 +434,7 @@
ASSERT_EQ(0, OpenArchiveFd(fd, "EntryLargerThan32KTest", &handle));
ZipEntry entry;
- ZipEntryName ab_name;
+ ZipString ab_name;
ab_name.name = kAbTxtName;
ab_name.name_length = kAbTxtNameLength;
ASSERT_EQ(0, FindEntry(handle, ab_name, &entry));
@@ -392,7 +502,7 @@
ASSERT_EQ(0, OpenArchiveWrapper(kValidZip, &handle));
ZipEntry entry;
- ZipEntryName name;
+ ZipString name;
name.name = kATxtName;
name.name_length = kATxtNameLength;
ASSERT_EQ(0, FindEntry(handle, name, &entry));
diff --git a/logd/LogAudit.cpp b/logd/LogAudit.cpp
index 4ec2e59..4b3547c 100644
--- a/logd/LogAudit.cpp
+++ b/logd/LogAudit.cpp
@@ -145,7 +145,9 @@
++cp;
}
tid = pid;
+ logbuf->lock();
uid = logbuf->pidToUid(pid);
+ logbuf->unlock();
memmove(pidptr, cp, strlen(cp) + 1);
}
@@ -180,14 +182,20 @@
static const char comm_str[] = " comm=\"";
const char *comm = strstr(str, comm_str);
const char *estr = str + strlen(str);
+ char *commfree = NULL;
if (comm) {
estr = comm;
comm += sizeof(comm_str) - 1;
} else if (pid == getpid()) {
pid = tid;
comm = "auditd";
- } else if (!(comm = logbuf->pidToName(pid))) {
- comm = "unknown";
+ } else {
+ logbuf->lock();
+ comm = commfree = logbuf->pidToName(pid);
+ logbuf->unlock();
+ if (!comm) {
+ comm = "unknown";
+ }
}
const char *ecomm = strchr(comm, '"');
@@ -218,6 +226,7 @@
}
}
+ free(commfree);
free(str);
if (notify) {
diff --git a/logd/LogBuffer.h b/logd/LogBuffer.h
index 00b19b6..a13fded 100644
--- a/logd/LogBuffer.h
+++ b/logd/LogBuffer.h
@@ -71,10 +71,12 @@
// *strp uses malloc, use free to release.
void formatPrune(char **strp) { mPrune.format(strp); }
- // helper
+ // helper must be protected directly or implicitly by lock()/unlock()
char *pidToName(pid_t pid) { return stats.pidToName(pid); }
uid_t pidToUid(pid_t pid) { return stats.pidToUid(pid); }
char *uidToName(uid_t uid) { return stats.uidToName(uid); }
+ void lock() { pthread_mutex_lock(&mLogElementsLock); }
+ void unlock() { pthread_mutex_unlock(&mLogElementsLock); }
private:
void maybePrune(log_id_t id);
diff --git a/logd/LogBufferElement.cpp b/logd/LogBufferElement.cpp
index 3f5fdce..9fb1439 100644
--- a/logd/LogBufferElement.cpp
+++ b/logd/LogBufferElement.cpp
@@ -111,13 +111,17 @@
}
static const char format_uid[] = "uid=%u%s%s expire %u line%s";
+ parent->lock();
char *name = parent->uidToName(mUid);
+ parent->unlock();
char *commName = android::tidToName(mTid);
if (!commName && (mTid != mPid)) {
commName = android::tidToName(mPid);
}
if (!commName) {
+ parent->lock();
commName = parent->pidToName(mPid);
+ parent->unlock();
}
size_t len = name ? strlen(name) : 0;
if (len && commName && !strncmp(name, commName, len)) {
diff --git a/logd/LogStatistics.h b/logd/LogStatistics.h
index b9e9650..760d6b2 100644
--- a/logd/LogStatistics.h
+++ b/logd/LogStatistics.h
@@ -334,7 +334,7 @@
// *strp = malloc, balance with free
void format(char **strp, uid_t uid, unsigned int logMask);
- // helper
+ // helper (must be locked directly or implicitly by mLogElementsLock)
char *pidToName(pid_t pid);
uid_t pidToUid(pid_t pid);
char *uidToName(uid_t uid);
diff --git a/rootdir/Android.mk b/rootdir/Android.mk
index 7ab76b8..de10535 100644
--- a/rootdir/Android.mk
+++ b/rootdir/Android.mk
@@ -26,10 +26,15 @@
#
# create some directories (some are mount points)
LOCAL_POST_INSTALL_CMD := mkdir -p $(addprefix $(TARGET_ROOT_OUT)/, \
- sbin dev proc sys system data oem)
+ sbin dev proc sys system data oem acct config storage mnt root)
include $(BUILD_SYSTEM)/base_rules.mk
+EXPORT_GLOBAL_ASAN_OPTIONS :=
+ifeq (address,$(strip $(SANITIZE_TARGET)))
+ EXPORT_GLOBAL_ASAN_OPTIONS := export ASAN_OPTIONS allow_user_segv_handler=1:detect_odr_violation=0:alloc_dealloc_mismatch=0
+endif
+
# Regenerate init.environ.rc if PRODUCT_BOOTCLASSPATH has changed.
bcp_md5 := $(word 1, $(shell echo $(PRODUCT_BOOTCLASSPATH) $(PRODUCT_SYSTEM_SERVER_CLASSPATH) | $(MD5SUM)))
bcp_dep := $(intermediates)/$(bcp_md5).bcp.dep
@@ -41,6 +46,7 @@
@mkdir -p $(dir $@)
$(hide) sed -e 's?%BOOTCLASSPATH%?$(PRODUCT_BOOTCLASSPATH)?g' $< >$@
$(hide) sed -i -e 's?%SYSTEMSERVERCLASSPATH%?$(PRODUCT_SYSTEM_SERVER_CLASSPATH)?g' $@
+ $(hide) sed -i -e 's?%EXPORT_GLOBAL_ASAN_OPTIONS%?$(EXPORT_GLOBAL_ASAN_OPTIONS)?g' $@
bcp_md5 :=
bcp_dep :=
diff --git a/rootdir/init.environ.rc.in b/rootdir/init.environ.rc.in
index 0064790..e8b46eb 100644
--- a/rootdir/init.environ.rc.in
+++ b/rootdir/init.environ.rc.in
@@ -9,3 +9,4 @@
export LOOP_MOUNTPOINT /mnt/obb
export BOOTCLASSPATH %BOOTCLASSPATH%
export SYSTEMSERVERCLASSPATH %SYSTEMSERVERCLASSPATH%
+ %EXPORT_GLOBAL_ASAN_OPTIONS%
diff --git a/rootdir/init.rc b/rootdir/init.rc
index 72df0f5..be5292a 100644
--- a/rootdir/init.rc
+++ b/rootdir/init.rc
@@ -19,9 +19,6 @@
start ueventd
- # create mountpoints
- mkdir /mnt 0775 root system
-
on init
sysclktz 0
@@ -32,8 +29,7 @@
# Link /vendor to /system/vendor for devices without a vendor partition.
symlink /system/vendor /vendor
- # Create cgroup mount point for cpu accounting
- mkdir /acct
+ # Mount cgroup mount point for cpu accounting
mount cgroup none /acct cpuacct
mkdir /acct/uid
@@ -50,11 +46,6 @@
chown root system /sys/fs/cgroup/memory/sw/tasks
chmod 0660 /sys/fs/cgroup/memory/sw/tasks
- mkdir /system
- mkdir /data 0771 system system
- mkdir /cache 0770 system cache
- mkdir /config 0500 root root
-
# See storage config details at http://source.android.com/tech/storage/
mkdir /mnt/shell 0700 shell shell
mkdir /mnt/media_rw 0700 media_rw media_rw