From a2ebbb29cdf595208abdb88bec31f0a43f23d21b Mon Sep 17 00:00:00 2001 From: Douglas Katzman Date: Fri, 10 Jul 2020 22:24:51 -0400 Subject: [PATCH] Remove os-provides-putwc and backtrace's use of putwc It took me half a day to find out why stderr could stop working entirely while fd 2 itself was fine. Thanks to rongut @ google the answer is hidden within https://man7.org/linux/man-pages/man3/fwide.3.html - "Once a stream has an orientation, it cannot be changed and persists until the stream is closed." ("orientation" means "element width") Using the wrong function can bork the stream so it appears inoperative. Since I don't think the right thing is to change *all* fprintf calls to fwprintf etc etc to accomodate widechar, the solution is to completely avoid using the widechar-oriented functions. --- .gitignore | 2 - make-target-2-load.lisp | 3 +- src/runtime/backtrace.c | 61 ++++++++---------------- src/runtime/immobile-space.c | 12 +---- src/runtime/lispstring.h | 35 ++++++++++++++ tools-for-build/grovel-features.sh | 2 - tools-for-build/os-provides-putwc-test.c | 11 ----- 7 files changed, 56 insertions(+), 70 deletions(-) create mode 100644 src/runtime/lispstring.h delete mode 100644 tools-for-build/os-provides-putwc-test.c diff --git a/.gitignore b/.gitignore index 158add5d2..2ea1e4263 100644 --- a/.gitignore +++ b/.gitignore @@ -45,8 +45,6 @@ tools-for-build/determine-endianness.exe tools-for-build/grovel-headers tools-for-build/grovel-headers.exe tools-for-build/mmap-rwx -tools-for-build/os-provides-putwc-test -tools-for-build/os-provides-putwc-test.exe tools-for-build/where-is-mcontext contrib/*/test-passed contrib/*/test-output diff --git a/make-target-2-load.lisp b/make-target-2-load.lisp index a0fa29032..e761d3de3 100644 --- a/make-target-2-load.lisp +++ b/make-target-2-load.lisp @@ -24,8 +24,7 @@ ;; "LISP_FEATURE_" on the corresponding #define is unfortunate. :GCC-TLS :RESTORE-FS-SEGMENT-REGISTER-FROM-TLS ; only for 'src/runtime/thread.h' - :OS-PROVIDES-BLKSIZE-T ; only for 'src/runtime/wrap.h' - :OS-PROVIDES-PUTWC)) ; only for 'src/runtime/backtrace.c' + :OS-PROVIDES-BLKSIZE-T)) ; only for 'src/runtime/wrap.h' (public-features (cons sb-impl::!sbcl-architecture diff --git a/src/runtime/backtrace.c b/src/runtime/backtrace.c index 23cea40be..f82acd0b7 100644 --- a/src/runtime/backtrace.c +++ b/src/runtime/backtrace.c @@ -36,25 +36,12 @@ #include "code.h" #include "var-io.h" #include "forwarding-ptr.h" +#include "lispstring.h" #ifdef LISP_FEATURE_OS_PROVIDES_DLADDR # include #endif -static void -sbcl_putwc(wchar_t c, FILE *file) -{ -#ifdef LISP_FEATURE_OS_PROVIDES_PUTWC - putwc(c, file); -#else - if (c < 256) { - fputc(c, file); - } else { - fputc('?', file); - } -#endif -} - static int decode_locs(lispobj packed_integer, int *offset, int *elsewhere) { struct varint_unpacker unpacker; @@ -106,34 +93,24 @@ debug_function_from_pc (struct code* code, void *pc) static void print_string (struct vector *vector, FILE *f) { - int tag = widetag_of(&vector->header); - -#define doit(TYPE) \ - do { \ - int i; \ - int n = fixnum_value(vector->length); \ - TYPE *data = (TYPE *) vector->data; \ - for (i = 0; i < n; i++) { \ - wchar_t c = (wchar_t) data[i]; \ - if (c == '\\' || c == '"') \ - putc('\\', f); \ - sbcl_putwc(c, f); \ - } \ - } while (0) - - switch (tag) { - case SIMPLE_BASE_STRING_WIDETAG: - doit(unsigned char); - break; -#ifdef SIMPLE_CHARACTER_STRING_WIDETAG - case SIMPLE_CHARACTER_STRING_WIDETAG: - doit(unsigned int); - break; -#endif - default: - fprintf(f, "", tag); - } -#undef doit + if (!string_widetag_p(widetag_of(&vector->header))) { + fprintf(f, "", widetag_of(&vector->header)); + return; + } + int i; + int n = fixnum_value(vector->length); + for (i = 0; i < n; i++) { + unsigned int c = schar(vector, i); + if (c > 0xFFFF) fprintf(f,"\\U%08x", c); + // without knowing whether the terminal can accept + // character codes 128 through 255, it's conservative + // to just output unicode escapes. + else if (c > 0x7F) fprintf(f,"\\u%04x", c); + else { + if (c == '\\' || c == '"') putc('\\', f); + putc(c, f); + } + } } static int string_equal (struct vector *vector, char *string) diff --git a/src/runtime/immobile-space.c b/src/runtime/immobile-space.c index 8325a3f13..03ea79d46 100644 --- a/src/runtime/immobile-space.c +++ b/src/runtime/immobile-space.c @@ -58,6 +58,7 @@ #include "immobile-space.h" #include "unaligned.h" #include "code.h" +#include "lispstring.h" #include #include @@ -1727,17 +1728,6 @@ static lispobj* get_load_address(lispobj* old) } #if DEFRAGMENT_FIXEDOBJ_SUBSPACE -// This does not accept (SIMPLE-ARRAY NIL (*)) -// (You'd have a pretty bad time trying making a symbol like that) -static int schar(struct vector* string, int index) -{ -#ifdef LISP_FEATURE_SB_UNICODE - if (widetag_of(&string->header) == SIMPLE_CHARACTER_STRING_WIDETAG) - return ((int*)string->data)[index]; -#endif - return ((char*)string->data)[index]; -} - #include "genesis/package.h" #define N_SYMBOL_KINDS 5 diff --git a/src/runtime/lispstring.h b/src/runtime/lispstring.h new file mode 100644 index 000000000..6ed9422a2 --- /dev/null +++ b/src/runtime/lispstring.h @@ -0,0 +1,35 @@ +/* + * This software is part of the SBCL system. See the README file for + * more information. + * + * This software is derived from the CMU CL system, which was + * written at Carnegie Mellon University and released into the + * public domain. The software is in the public domain and is + * provided with absolutely no warranty. See the COPYING and CREDITS + * files for more information. + */ + +#ifndef _LISPSTRING_H_ +#define _LISPSTRING_H_ + +static inline boolean string_widetag_p(int widetag) +{ + // element type of NIL can just go to hell + return widetag == SIMPLE_BASE_STRING_WIDETAG +#ifdef SIMPLE_CHARACTER_STRING_WIDETAG + || widetag == SIMPLE_CHARACTER_STRING_WIDETAG +#endif + ; +} + +// This does not accept (SIMPLE-ARRAY NIL (*)) +// (You'd have a pretty bad time trying making a symbol like that) +static inline unsigned int schar(struct vector* string, int index) +{ + if (widetag_of(&string->header) == SIMPLE_BASE_STRING_WIDETAG) + return ((char*)string->data)[index]; + else + return ((unsigned int*)string->data)[index]; +} + +#endif diff --git a/tools-for-build/grovel-features.sh b/tools-for-build/grovel-features.sh index baf677803..7410fc0cb 100644 --- a/tools-for-build/grovel-features.sh +++ b/tools-for-build/grovel-features.sh @@ -23,8 +23,6 @@ featurep os-provides-dlopen featurep os-provides-dladdr -featurep os-provides-putwc - featurep os-provides-blksize-t featurep os-provides-suseconds-t diff --git a/tools-for-build/os-provides-putwc-test.c b/tools-for-build/os-provides-putwc-test.c deleted file mode 100644 index 676f13586..000000000 --- a/tools-for-build/os-provides-putwc-test.c +++ /dev/null @@ -1,11 +0,0 @@ -/* test to build and run so that we know if we have putwc */ - -#include -#include - -int main () -{ - wchar_t a = 'a'; - putwc(a, stdout); - return 104; -}