From 162558382b768a4120b3e41090a4c7b53f11469a Mon Sep 17 00:00:00 2001 From: Tianjie Xu Date: Sat, 30 Apr 2016 11:49:59 -0700 Subject: Allow recovery to return error codes Write error code, cause code, and retry count into last_install. So we can have more information about the reason of a failed OTA. Example of new last_install: @/cache/recovery/block.map package name 0 install result retry: 1 retry count (new) error: 30 error code (new) cause: 12 error cause (new) Details in: go/android-ota-errorcode Bug: 28471955 Change-Id: I00e7153c821e7355c1be81a86c7f228108f3dc37 --- edify/Android.mk | 4 ++++ edify/expr.cpp | 39 +++++++++++++++++++++++++++++---------- edify/expr.h | 18 +++++++++++++++++- 3 files changed, 50 insertions(+), 11 deletions(-) (limited to 'edify') diff --git a/edify/Android.mk b/edify/Android.mk index 038dec088..71cf7652a 100644 --- a/edify/Android.mk +++ b/edify/Android.mk @@ -22,6 +22,8 @@ LOCAL_YACCFLAGS := -v LOCAL_CPPFLAGS += -Wno-unused-parameter LOCAL_CPPFLAGS += -Wno-deprecated-register LOCAL_CLANG := true +LOCAL_C_INCLUDES += $(LOCAL_PATH)/.. +LOCAL_STATIC_LIBRARIES += libbase include $(BUILD_HOST_EXECUTABLE) @@ -36,5 +38,7 @@ LOCAL_CPPFLAGS := -Wno-unused-parameter LOCAL_CPPFLAGS += -Wno-deprecated-register LOCAL_MODULE := libedify LOCAL_CLANG := true +LOCAL_C_INCLUDES += $(LOCAL_PATH)/.. +LOCAL_STATIC_LIBRARIES += libbase include $(BUILD_STATIC_LIBRARY) diff --git a/edify/expr.cpp b/edify/expr.cpp index cd1e08726..cc14fbe93 100644 --- a/edify/expr.cpp +++ b/edify/expr.cpp @@ -21,6 +21,11 @@ #include #include +#include + +#include +#include + #include "expr.h" // Functions should: @@ -36,7 +41,7 @@ char* Evaluate(State* state, Expr* expr) { Value* v = expr->fn(expr->name, state, expr->argc, expr->argv); if (v == NULL) return NULL; if (v->type != VAL_STRING) { - ErrorAbort(state, "expecting string, got value type %d", v->type); + ErrorAbort(state, kArgsParsingFailure, "expecting string, got value type %d", v->type); FreeValue(v); return NULL; } @@ -493,15 +498,29 @@ Value** ReadValueVarArgs(State* state, int argc, Expr* argv[]) { return args; } +static void ErrorAbortV(State* state, const char* format, va_list ap) { + std::string buffer; + android::base::StringAppendV(&buffer, format, ap); + free(state->errmsg); + state->errmsg = strdup(buffer.c_str()); + return; +} + // Use printf-style arguments to compose an error message to put into -// *state. Returns NULL. +// *state. Returns nullptr. Value* ErrorAbort(State* state, const char* format, ...) { - char* buffer = reinterpret_cast(malloc(4096)); - va_list v; - va_start(v, format); - vsnprintf(buffer, 4096, format, v); - va_end(v); - free(state->errmsg); - state->errmsg = buffer; - return NULL; + va_list ap; + va_start(ap, format); + ErrorAbortV(state, format, ap); + va_end(ap); + return nullptr; +} + +Value* ErrorAbort(State* state, CauseCode cause_code, const char* format, ...) { + va_list ap; + va_start(ap, format); + ErrorAbortV(state, format, ap); + va_end(ap); + state->cause_code = cause_code; + return nullptr; } diff --git a/edify/expr.h b/edify/expr.h index 36f8e9612..5c06de846 100644 --- a/edify/expr.h +++ b/edify/expr.h @@ -19,6 +19,7 @@ #include +#include "error_code.h" #include "yydefs.h" #define MAX_STRING_LEN 1024 @@ -39,6 +40,15 @@ typedef struct { // Should be NULL initially, will be either NULL or a malloc'd // pointer after Evaluate() returns. char* errmsg; + + // error code indicates the type of failure (e.g. failure to update system image) + // during the OTA process. + ErrorCode error_code = kNoError; + + // cause code provides more detailed reason of an OTA failure (e.g. fsync error) + // in addition to the error code. + CauseCode cause_code = kNoCause; + } State; #define VAL_STRING 1 // data will be NULL-terminated; size doesn't count null @@ -152,7 +162,13 @@ Value** ReadValueVarArgs(State* state, int argc, Expr* argv[]); // Use printf-style arguments to compose an error message to put into // *state. Returns NULL. -Value* ErrorAbort(State* state, const char* format, ...) __attribute__((format(printf, 2, 3))); +Value* ErrorAbort(State* state, const char* format, ...) + __attribute__((format(printf, 2, 3), deprecated)); + +// ErrorAbort has an optional (but recommended) argument 'cause_code'. If the cause code +// is set, it will be logged into last_install and provides reason of OTA failures. +Value* ErrorAbort(State* state, CauseCode cause_code, const char* format, ...) + __attribute__((format(printf, 3, 4))); // Wrap a string into a Value, taking ownership of the string. Value* StringValue(char* str); -- cgit v1.2.3