| From 521fbe9135ce7eefd190f8a2c50b00be428def6c Mon Sep 17 00:00:00 2001 |
| From: Jon Turney <jon.turney@dronecode.org.uk> |
| Date: Wed, 9 Apr 2014 23:49:03 +0100 |
| Subject: [PATCH 17/29] Provide a working strtok_r for MinGW |
| |
| Prior to mingW-w64 3.3.0, strtok_r was a macro using strtok, which causes the |
| processor to not work, as re-entrancy is required |
| |
| v2: |
| Link various unit tests with @LIBOBJS@ for strtok_r |
| |
| Signed-off-by: Jon Turney <jon.turney@dronecode.org.uk> |
| --- |
| Makefile.am | 28 +++++----- |
| compat/strtok_r.c | 85 +++++++++++++++++++++++++++++ |
| configure.ac | 3 + |
| src/processor/basic_source_line_resolver.cc | 4 ++ |
| src/processor/cfi_frame_info.cc | 6 +- |
| src/processor/tokenize.cc | 6 +- |
| 6 files changed, 116 insertions(+), 16 deletions(-) |
| create mode 100644 compat/strtok_r.c |
| |
| diff --git a/Makefile.am b/Makefile.am |
| index 39aec328..43d28f6a 100644 |
| --- a/Makefile.am |
| +++ b/Makefile.am |
| @@ -833,7 +833,7 @@ src_processor_basic_source_line_resolver_unittest_LDADD = \ |
| src/processor/source_line_resolver_base.o \ |
| src/processor/tokenize.o \ |
| $(TEST_LIBS) \ |
| - $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
| + $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@ |
| |
| src_processor_cfi_frame_info_unittest_SOURCES = \ |
| src/processor/cfi_frame_info_unittest.cc |
| @@ -842,7 +842,7 @@ src_processor_cfi_frame_info_unittest_LDADD = \ |
| src/processor/logging.o \ |
| src/processor/pathname_stripper.o \ |
| $(TEST_LIBS) \ |
| - $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
| + $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@ |
| src_processor_cfi_frame_info_unittest_CPPFLAGS = \ |
| $(AM_CPPFLAGS) $(TEST_CFLAGS) |
| |
| @@ -891,7 +891,7 @@ src_processor_exploitability_unittest_LDADD = \ |
| src/processor/tokenize.o \ |
| src/third_party/libdisasm/libdisasm.a \ |
| $(TEST_LIBS) \ |
| - $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
| + $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@ |
| |
| src_processor_disassembler_x86_unittest_SOURCES = \ |
| src/processor/disassembler_x86_unittest.cc |
| @@ -918,7 +918,7 @@ src_processor_fast_source_line_resolver_unittest_LDADD = \ |
| src/processor/source_line_resolver_base.o \ |
| src/processor/tokenize.o \ |
| $(TEST_LIBS) \ |
| - $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
| + $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@ |
| |
| src_processor_map_serializers_unittest_SOURCES = \ |
| src/processor/map_serializers_unittest.cc |
| @@ -961,7 +961,7 @@ src_processor_microdump_processor_unittest_LDADD = \ |
| src/processor/stackwalker_x86.o \ |
| src/processor/tokenize.o \ |
| $(TEST_LIBS) \ |
| - $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
| + $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@ |
| |
| src_processor_minidump_processor_unittest_SOURCES = \ |
| src/processor/minidump_processor_unittest.cc |
| @@ -1001,7 +1001,7 @@ src_processor_minidump_processor_unittest_LDADD = \ |
| src/processor/tokenize.o \ |
| src/third_party/libdisasm/libdisasm.a \ |
| $(TEST_LIBS) \ |
| - $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
| + $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@ |
| |
| src_processor_minidump_unittest_SOURCES = \ |
| src/common/test_assembler.cc \ |
| @@ -1138,7 +1138,7 @@ src_processor_stackwalker_amd64_unittest_SOURCES = \ |
| src_processor_stackwalker_amd64_unittest_LDADD = \ |
| src/libbreakpad.a \ |
| $(TEST_LIBS) \ |
| - $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
| + $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@ |
| src_processor_stackwalker_amd64_unittest_CPPFLAGS = \ |
| $(AM_CPPFLAGS) $(TEST_CFLAGS) |
| |
| @@ -1148,7 +1148,7 @@ src_processor_stackwalker_arm_unittest_SOURCES = \ |
| src_processor_stackwalker_arm_unittest_LDADD = \ |
| src/libbreakpad.a \ |
| $(TEST_LIBS) \ |
| - $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
| + $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@ |
| src_processor_stackwalker_arm_unittest_CPPFLAGS = \ |
| $(AM_CPPFLAGS) $(TEST_CFLAGS) |
| |
| @@ -1158,7 +1158,7 @@ src_processor_stackwalker_arm64_unittest_SOURCES = \ |
| src_processor_stackwalker_arm64_unittest_LDADD = \ |
| src/libbreakpad.a \ |
| $(TEST_LIBS) \ |
| - $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
| + $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@ |
| src_processor_stackwalker_arm64_unittest_CPPFLAGS = \ |
| $(AM_CPPFLAGS) $(TEST_CFLAGS) |
| |
| @@ -1168,7 +1168,7 @@ src_processor_stackwalker_address_list_unittest_SOURCES = \ |
| src_processor_stackwalker_address_list_unittest_LDADD = \ |
| src/libbreakpad.a \ |
| $(TEST_LIBS) \ |
| - $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
| + $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@ |
| src_processor_stackwalker_address_list_unittest_CPPFLAGS = \ |
| $(AM_CPPFLAGS) $(TEST_CFLAGS) |
| |
| @@ -1178,7 +1178,7 @@ src_processor_stackwalker_mips_unittest_SOURCES = \ |
| src_processor_stackwalker_mips_unittest_LDADD = \ |
| src/libbreakpad.a \ |
| $(TEST_LIBS) \ |
| - $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
| + $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@ |
| src_processor_stackwalker_mips_unittest_CPPFLAGS = \ |
| $(AM_CPPFLAGS) $(TEST_CFLAGS) |
| |
| @@ -1198,7 +1198,7 @@ src_processor_stackwalker_x86_unittest_SOURCES = \ |
| src_processor_stackwalker_x86_unittest_LDADD = \ |
| src/libbreakpad.a \ |
| $(TEST_LIBS) \ |
| - $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) |
| + $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) @LIBOBJS@ |
| src_processor_stackwalker_x86_unittest_CPPFLAGS = \ |
| $(AM_CPPFLAGS) $(TEST_CFLAGS) |
| |
| @@ -1273,7 +1273,7 @@ src_processor_microdump_stackwalk_LDADD = \ |
| src/processor/stackwalker_x86.o \ |
| src/processor/tokenize.o \ |
| src/third_party/libdisasm/libdisasm.a \ |
| - $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) $(SOCKET_LIBS) |
| + $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) $(SOCKET_LIBS) @LIBOBJS@ |
| |
| src_processor_minidump_stackwalk_SOURCES = \ |
| src/processor/minidump_stackwalk.cc |
| @@ -1313,7 +1313,7 @@ src_processor_minidump_stackwalk_LDADD = \ |
| src/processor/symbolic_constants_win.o \ |
| src/processor/tokenize.o \ |
| src/third_party/libdisasm/libdisasm.a \ |
| - $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) $(SOCKET_LIBS) |
| + $(PTHREAD_CFLAGS) $(PTHREAD_LIBS) $(SOCKET_LIBS) @LIBOBJS@ |
| |
| endif !DISABLE_PROCESSOR |
| |
| diff --git a/compat/strtok_r.c b/compat/strtok_r.c |
| new file mode 100644 |
| index 00000000..ec7b6379 |
| --- /dev/null |
| +++ b/compat/strtok_r.c |
| @@ -0,0 +1,85 @@ |
| +/*- |
| + * Copyright (c) 1998 Softweyr LLC. All rights reserved. |
| + * |
| + * strtok_r, from Berkeley strtok |
| + * Oct 13, 1998 by Wes Peters <wes@softweyr.com> |
| + * |
| + * Copyright (c) 1988, 1993 |
| + * The Regents of the University of California. All rights reserved. |
| + * |
| + * Redistribution and use in source and binary forms, with or without |
| + * modification, are permitted provided that the following conditions |
| + * are met: |
| + * 1. Redistributions of source code must retain the above copyright |
| + * notices, this list of conditions and the following disclaimer. |
| + * 2. Redistributions in binary form must reproduce the above copyright |
| + * notices, this list of conditions and the following disclaimer in the |
| + * documentation and/or other materials provided with the distribution. |
| + * 3. All advertising materials mentioning features or use of this software |
| + * must display the following acknowledgement: |
| + * This product includes software developed by Softweyr LLC, the |
| + * University of California, Berkeley, and its contributors. |
| + * 4. Neither the name of the University nor the names of its contributors |
| + * may be used to endorse or promote products derived from this software |
| + * without specific prior written permission. |
| + * |
| + * THIS SOFTWARE IS PROVIDED BY SOFTWEYR LLC, THE REGENTS AND CONTRIBUTORS |
| + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A |
| + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SOFTWEYR LLC, THE |
| + * REGENTS, OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED |
| + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
| + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
| + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| + */ |
| + |
| +#include <string.h> |
| + |
| +char * |
| +strtok_r(char *s, const char *delim, char **last) |
| +{ |
| + char *spanp, *tok; |
| + int c, sc; |
| + |
| + if (s == NULL && (s = *last) == NULL) |
| + return (NULL); |
| + |
| + /* |
| + * Skip (span) leading delimiters (s += strspn(s, delim), sort of). |
| + */ |
| +cont: |
| + c = *s++; |
| + for (spanp = (char *)delim; (sc = *spanp++) != 0;) { |
| + if (c == sc) |
| + goto cont; |
| + } |
| + |
| + if (c == 0) { /* no non-delimiter characters */ |
| + *last = NULL; |
| + return (NULL); |
| + } |
| + tok = s - 1; |
| + |
| + /* |
| + * Scan token (scan for delimiters: s += strcspn(s, delim), sort of). |
| + * Note that delim must have one NUL; we stop if we see that, too. |
| + */ |
| + for (;;) { |
| + c = *s++; |
| + spanp = (char *)delim; |
| + do { |
| + if ((sc = *spanp++) == c) { |
| + if (c == 0) |
| + s = NULL; |
| + else |
| + s[-1] = '\0'; |
| + *last = s; |
| + return (tok); |
| + } |
| + } while (sc != 0); |
| + } |
| + /* NOTREACHED */ |
| +} |
| diff --git a/configure.ac b/configure.ac |
| index 93635de5..da8c49a3 100644 |
| --- a/configure.ac |
| +++ b/configure.ac |
| @@ -78,6 +78,9 @@ AC_CHECK_FUNCS([arc4random getrandom]) |
| |
| AX_CXX_COMPILE_STDCXX(11, noext, mandatory) |
| |
| +AC_CONFIG_LIBOBJ_DIR([compat]) |
| +AC_REPLACE_FUNCS([strtok_r]) |
| + |
| dnl Test supported warning flags. |
| WARN_CXXFLAGS= |
| dnl This warning flag is used by clang. Its default behavior is to warn when |
| diff --git a/src/processor/basic_source_line_resolver.cc b/src/processor/basic_source_line_resolver.cc |
| index aa66e159..b7ee7d17 100644 |
| --- a/src/processor/basic_source_line_resolver.cc |
| +++ b/src/processor/basic_source_line_resolver.cc |
| @@ -49,6 +49,10 @@ |
| |
| #include "processor/tokenize.h" |
| |
| +#ifndef HAVE_STRTOK_R |
| +extern "C" char *strtok_r(char *, const char *, char **); |
| +#endif |
| + |
| using std::map; |
| using std::vector; |
| using std::make_pair; |
| diff --git a/src/processor/cfi_frame_info.cc b/src/processor/cfi_frame_info.cc |
| index 0c4af7ba..dd2b438b 100644 |
| --- a/src/processor/cfi_frame_info.cc |
| +++ b/src/processor/cfi_frame_info.cc |
| @@ -41,12 +41,16 @@ |
| #include "common/scoped_ptr.h" |
| #include "processor/postfix_evaluator-inl.h" |
| |
| -namespace google_breakpad { |
| +#ifndef HAVE_STRTOK_R |
| +extern "C" char *strtok_r(char *, const char *, char **); |
| +#endif |
| |
| #ifdef _MSC_VER |
| #define strtok_r strtok_s |
| #endif |
| |
| +namespace google_breakpad { |
| + |
| template<typename V> |
| bool CFIFrameInfo::FindCallerRegs(const RegisterValueMap<V> ®isters, |
| const MemoryRegion &memory, |
| diff --git a/src/processor/tokenize.cc b/src/processor/tokenize.cc |
| index 8fce87a2..e6213ac3 100644 |
| --- a/src/processor/tokenize.cc |
| +++ b/src/processor/tokenize.cc |
| @@ -34,12 +34,16 @@ |
| |
| #include "common/using_std_string.h" |
| |
| -namespace google_breakpad { |
| +#ifndef HAVE_STRTOK_R |
| +extern "C" char *strtok_r(char *, const char *, char **); |
| +#endif |
| |
| #ifdef _MSC_VER |
| #define strtok_r strtok_s |
| #endif |
| |
| +namespace google_breakpad { |
| + |
| using std::vector; |
| |
| bool Tokenize(char *line, |
| -- |
| 2.15.0 |
| |