diff --git a/Android/android.py b/Android/android.py index c5b599400f1c7b5..549e4ffecd10ca9 100755 --- a/Android/android.py +++ b/Android/android.py @@ -32,7 +32,7 @@ TESTBED_DIR = ANDROID_DIR / "testbed" CROSS_BUILD_DIR = PYTHON_DIR / "cross-build" -HOSTS = ["aarch64-linux-android", "x86_64-linux-android"] +HOSTS = ["aarch64-linux-android", "x86_64-linux-android", "arm-linux-androideabi", "i686-linux-android"], APP_ID = "org.python.testbed" DECODE_ARGS = ("UTF-8", "backslashreplace") diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 8cc6bd0fa789060..5180518b774c43c 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -72,6 +72,10 @@ # include // F_GETFD #endif +#ifdef __ANDROID__ +# include +#endif + #ifdef MS_WINDOWS # undef BYTE #endif @@ -281,12 +285,21 @@ _coerce_default_locale_settings(int warn, const _LocaleCoercionTarget *target) /* Set the relevant locale environment variable */ if (setenv("LC_CTYPE", newloc, 1)) { +#ifdef __ANDROID__ + __android_log_write(ANDROID_LOG_ERROR, "python.stderr", + "Error setting LC_CTYPE, skipping C locale coercion"); +#else fprintf(stderr, "Error setting LC_CTYPE, skipping C locale coercion\n"); +#endif return 0; } if (warn) { +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_WARN, "python.stderr", C_LOCALE_COERCION_WARNING, newloc); +#else fprintf(stderr, C_LOCALE_COERCION_WARNING, newloc); +#endif } /* Reconfigure with the overridden environment variables */ @@ -390,8 +403,13 @@ _Py_SetLocaleFromEnv(int category) * extension modules), so we make sure that they match the locale * configuration */ if (setenv("LC_CTYPE", utf8_locale, 1)) { +#ifdef __ANDROID__ + __android_log_print(ANDROID_LOG_WARN, "python.stderr", + "Warning: failed setting the LC_CTYPE environment variable to %s", utf8_locale); +#else fprintf(stderr, "Warning: failed setting the LC_CTYPE " "environment variable to %s\n", utf8_locale); +#endif } } #endif @@ -1166,12 +1184,22 @@ run_presite(PyThreadState *tstate) wcslen(config->run_presite) ); if (presite_modname == NULL) { +#ifdef __ANDROID__ + __android_log_write(ANDROID_LOG_ERROR, "python.stderr", + "Could not convert pre-site module name to unicode"); +#else fprintf(stderr, "Could not convert pre-site module name to unicode\n"); +#endif } else { PyObject *presite = PyImport_Import(presite_modname); if (presite == NULL) { +#ifdef __ANDROID__ + __android_log_write(ANDROID_LOG_ERROR, "python.stderr", + "pre-site import failed:"); +#else fprintf(stderr, "pre-site import failed:\n"); +#endif _PyErr_Print(tstate); } Py_XDECREF(presite); @@ -1302,7 +1330,11 @@ init_interp_main(PyThreadState *tstate) { PyObject *warnings_module = PyImport_ImportModule("warnings"); if (warnings_module == NULL) { +#ifdef __ANDROID__ + __android_log_write(ANDROID_LOG_ERROR, "Python", "'import warnings' failed; traceback:"); +#else fprintf(stderr, "'import warnings' failed; traceback:\n"); +#endif _PyErr_Print(tstate); } Py_XDECREF(warnings_module); @@ -2189,7 +2221,12 @@ _Py_Finalize(_PyRuntimeState *runtime) if (dump_refs_file != NULL) { dump_refs_fp = _Py_wfopen(dump_refs_file, L"w"); if (dump_refs_fp == NULL) { +#ifdef __ANDROID__ + __android_log_write(ANDROID_LOG_ERROR, "python.stderr", + "PYTHONDUMPREFSFILE: cannot create file: %ls", dump_refs_file); +#else fprintf(stderr, "PYTHONDUMPREFSFILE: cannot create file: %ls\n", dump_refs_file); +#endif } } @@ -3031,6 +3068,9 @@ static void _Py_FatalError_DumpTracebacks(int fd, PyInterpreterState *interp, PyThreadState *tstate) { +#ifdef __ANDROID__ + if (fd != 1 && fd != 2) +#endif PUTS(fd, "\n"); /* display the current Python stack */ @@ -3123,8 +3163,28 @@ fatal_output_debug(const char *msg) static void fatal_error_dump_runtime(int fd, _PyRuntimeState *runtime) { - PUTS(fd, "Python runtime state: "); PyThreadState *finalizing = _PyRuntimeState_GetFinalizing(runtime); +#ifdef __ANDROID__ + if (finalizing) { + __android_log_print(ANDROID_LOG_FATAL, "python.stderr", "Python runtime state: finalizing (tstate=%p)", finalizing); + } + else if (runtime->initialized) { + __android_log_write(ANDROID_LOG_FATAL, "python.stderr", "Python runtime state: initialized"); + } + else if (runtime->core_initialized) { + __android_log_write(ANDROID_LOG_FATAL, "python.stderr", "Python runtime state: core initialized"); + } + else if (runtime->preinitialized) { + __android_log_write(ANDROID_LOG_FATAL, "python.stderr", "Python runtime state: preinitialized"); + } + else if (runtime->preinitializing) { + __android_log_write(ANDROID_LOG_FATAL, "python.stderr", "Python runtime state: preinitializing"); + } + else { + __android_log_write(ANDROID_LOG_FATAL, "python.stderr", "Python runtime state: unknown"); + } +#else + PUTS(fd, "Python runtime state: "); if (finalizing) { PUTS(fd, "finalizing (tstate=0x"); _Py_DumpHexadecimal(fd, (uintptr_t)finalizing, sizeof(finalizing) * 2); @@ -3146,6 +3206,7 @@ fatal_error_dump_runtime(int fd, _PyRuntimeState *runtime) PUTS(fd, "unknown"); } PUTS(fd, "\n"); +#endif } @@ -3307,6 +3368,12 @@ fatal_error(int fd, int header, const char *prefix, const char *msg, reentrant = 1; if (header) { +#ifdef __ANDROID__ + if (prefix) + __android_log_print(ANDROID_LOG_FATAL, "python.stderr", "Fatal Python error: %s: %s", prefix, msg ? msg : ""); + else + __android_log_print(ANDROID_LOG_FATAL, "python.stderr", "Fatal Python error: %s", msg ? msg : ""); +#else PUTS(fd, "Fatal Python error: "); if (prefix) { PUTS(fd, prefix); @@ -3319,6 +3386,7 @@ fatal_error(int fd, int header, const char *prefix, const char *msg, PUTS(fd, ""); } PUTS(fd, "\n"); +#endif } _PyRuntimeState *runtime = &_PyRuntime; @@ -3402,6 +3470,14 @@ _Py_FatalErrorFormat(const char *func, const char *format, ...) } reentrant = 1; +#ifdef __ANDROID__ + va_list vargs; + va_start(vargs, format); + __android_log_vprint(ANDROID_LOG_FATAL, "python.stderr", format, vargs); + va_end(vargs); + + fatal_error(fileno(stderr), 0, NULL, NULL, -1); +#else FILE *stream = stderr; const int fd = fileno(stream); PUTS(fd, "Fatal Python error: "); @@ -3419,6 +3495,7 @@ _Py_FatalErrorFormat(const char *func, const char *format, ...) fflush(stream); fatal_error(fd, 0, NULL, NULL, -1); +#endif } diff --git a/Python/traceback.c b/Python/traceback.c index f8195c9ce9c090d..677986dfe471b33 100644 --- a/Python/traceback.c +++ b/Python/traceback.c @@ -22,6 +22,12 @@ # include // lseek() #endif +#ifdef __ANDROID__ +# include + +#define ANDROID_PRINT(fd, ...) __android_log_print(2 + fd * 2, fd == 2 ? "python.stderr" : "python.stdout", __VA_ARGS__) +#endif + #define OFF(x) offsetof(PyTracebackObject, x) #define PUTS(fd, str) (void)_Py_write_noraise(fd, str, (int)strlen(str)) @@ -902,6 +908,31 @@ dump_frame(int fd, _PyInterpreterFrame *frame) assert(frame->owner != FRAME_OWNED_BY_CSTACK); PyCodeObject *code =_PyFrame_GetCode(frame); + int lineno = PyUnstable_InterpreterFrame_GetLine(frame); + +#ifdef __ANDROID__ + if (fd == 1 || fd == 2) { + const char *name = "???"; + if (code != NULL && code->co_name != NULL + && PyUnicode_Check(code->co_name)) { + name = PyUnicode_AsUTF8(code->co_name); + } + + if (code != NULL && code->co_filename != NULL + && PyUnicode_Check(code->co_filename)) { + const char *fn = PyUnicode_AsUTF8(code->co_filename); + if (lineno >= 0) + ANDROID_PRINT(fd, "File \"%s\", line %lu, in %s", fn, (unsigned long)lineno, name); + else + ANDROID_PRINT(fd, "File \"%s\", line ???, in %s", fn, name); + } else if (lineno >= 0) + ANDROID_PRINT(fd, "File ???, line %lu, in %s", (unsigned long)lineno, name); + else + ANDROID_PRINT(fd, "File ???, line ???, in %s", name); + return; + } +#endif + PUTS(fd, " File "); if (code->co_filename != NULL && PyUnicode_Check(code->co_filename)) @@ -913,7 +944,6 @@ dump_frame(int fd, _PyInterpreterFrame *frame) PUTS(fd, "???"); } - int lineno = PyUnstable_InterpreterFrame_GetLine(frame); PUTS(fd, ", line "); if (lineno >= 0) { _Py_DumpDecimal(fd, (size_t)lineno); @@ -958,16 +988,31 @@ static void dump_traceback(int fd, PyThreadState *tstate, int write_header) { if (write_header) { +#ifdef __ANDROID__ + if (fd == 1 || fd == 2) + ANDROID_PRINT(fd, "Stack (most recent call first):"); + else +#endif PUTS(fd, "Stack (most recent call first):\n"); } if (tstate_is_freed(tstate)) { +#ifdef __ANDROID__ + if (fd == 1 || fd == 2) + ANDROID_PRINT(fd, " "); + else +#endif PUTS(fd, " \n"); return; } _PyInterpreterFrame *frame = tstate->current_frame; if (frame == NULL) { +#ifdef __ANDROID__ + if (fd == 1 || fd == 2) + ANDROID_PRINT(fd, " "); + else +#endif PUTS(fd, " \n"); return; } @@ -987,9 +1032,16 @@ dump_traceback(int fd, PyThreadState *tstate, int write_header) if (MAX_FRAME_DEPTH <= depth) { if (MAX_FRAME_DEPTH < depth) { - PUTS(fd, "plus "); - _Py_DumpDecimal(fd, depth); - PUTS(fd, " frames\n"); +#ifdef __ANDROID__ + if (fd == 1 || fd == 2) + ANDROID_PRINT(fd, "plus %u frames", depth); + else +#endif + { + PUTS(fd, "plus "); + _Py_DumpDecimal(fd, depth); + PUTS(fd, " frames\n"); + } } break; } @@ -1023,6 +1075,15 @@ _Py_DumpTraceback(int fd, PyThreadState *tstate) static void write_thread_id(int fd, PyThreadState *tstate, int is_current) { +#ifdef __ANDROID__ + if (fd == 1 || fd == 2) { + if (is_current) + ANDROID_PRINT(fd, "Current thread 0x%08lx (most recent call first):", tstate->thread_id); + else + ANDROID_PRINT(fd, "Thread 0x%08lx (most recent call first):", tstate->thread_id); + return; + } +#endif if (is_current) PUTS(fd, "Current thread 0x"); else @@ -1091,14 +1152,30 @@ _Py_DumpTracebackThreads(int fd, PyInterpreterState *interp, _Py_BEGIN_SUPPRESS_IPH do { - if (nthreads != 0) + if (nthreads != 0) { +#ifdef __ANDROID__ + if (fd == 1 || fd == 2) + ANDROID_PRINT(fd, ""); + else +#endif PUTS(fd, "\n"); + } if (nthreads >= MAX_NTHREADS) { +#ifdef __ANDROID__ + if (fd == 1 || fd == 2) + ANDROID_PRINT(fd, "..."); + else +#endif PUTS(fd, "...\n"); break; } write_thread_id(fd, tstate, tstate == current_tstate); if (tstate == current_tstate && tstate->interp->gc.collecting) { +#ifdef __ANDROID__ + if (fd == 1 || fd == 2) + ANDROID_PRINT(fd, " Garbage-collecting"); + else +#endif PUTS(fd, " Garbage-collecting\n"); } dump_traceback(fd, tstate, 0);