From f3883e19f984baa8981326d9e652d49433d49732 Mon Sep 17 00:00:00 2001 From: Brian Aker Date: Sun, 25 Dec 2011 12:18:57 -0800 Subject: [PATCH] Fix detangle, minor style cleanups. --- configure.ac | 6 ++ libmemcached/assert.hpp | 2 +- libmemcached/backtrace.cc | 107 ++++++++++++++++-------- libmemcached/backtrace.hpp | 1 - libmemcached/behavior.cc | 2 + libmemcached/flush_buffers.cc | 2 +- libmemcached/get.cc | 2 + libmemcached/io.cc | 2 + libmemcached/purge.cc | 50 ++++++++++- libmemcached/response.cc | 15 ++-- libmemcached/server.cc | 13 +-- libmemcached/server_list.cc | 2 +- libmemcached/stats.cc | 2 +- libmemcached/storage.cc | 39 +++++++-- m4/ax_cxx_gcc_abi_demangle.m4 | 58 +++++++++++++ tests/libmemcached-1.0/mem_functions.cc | 4 +- 16 files changed, 239 insertions(+), 68 deletions(-) create mode 100644 m4/ax_cxx_gcc_abi_demangle.m4 diff --git a/configure.ac b/configure.ac index 883fa3c4..602b4520 100644 --- a/configure.ac +++ b/configure.ac @@ -127,6 +127,10 @@ AC_CHECK_HEADERS([netinet/in.h]) AC_CHECK_HEADERS([stddef.h]) AC_CHECK_HEADERS([sys/time.h]) AC_CHECK_HEADERS([sasl/sasl.h]) +AC_CHECK_HEADERS([execinfo.h]) +AC_CHECK_HEADERS([cxxabi.h], + AC_DEFINE([HAVE_CXXABI_H], [1], [Have cxxabi.h]), + AC_DEFINE([HAVE_CXXABI_H], [0], [Have cxxabi.h])) AC_CXX_HEADER_STDCXX_98 AC_FUNC_ALLOCA @@ -154,6 +158,8 @@ AC_C_INLINE AC_C_VOLATILE AC_C_RESTRICT +AX_CXX_GCC_ABI_DEMANGLE + dnl The sasl functions should only be visible if we build with sasl support AS_IF([test "x$ac_cv_sasl" = "xyes"], [ diff --git a/libmemcached/assert.hpp b/libmemcached/assert.hpp index 787d844a..6858879c 100644 --- a/libmemcached/assert.hpp +++ b/libmemcached/assert.hpp @@ -49,7 +49,7 @@ do \ { \ if (not (__expr)) \ { \ - fprintf(stderr, "\nAssertion \"%s\" failed for function \"%s\" likely for %s, at %s:%d\n", #__expr, __func__, (#__mesg), __FILE__, __LINE__);\ + fprintf(stderr, "\n%s:%d Assertion \"%s\" failed for function \"%s\" likely for %s\n", __FILE__, __LINE__, #__expr, __func__, (#__mesg));\ custom_backtrace(); \ abort(); \ } \ diff --git a/libmemcached/backtrace.cc b/libmemcached/backtrace.cc index bc8846ba..8fb8acc7 100644 --- a/libmemcached/backtrace.cc +++ b/libmemcached/backtrace.cc @@ -40,69 +40,106 @@ #include #include -#ifdef __GNUC__ -#ifdef HAVE_BACKTRACE +#ifdef HAVE_EXECINFO_H #include +#endif + +#ifdef HAVE_CXXABI_H #include -#endif // HAVE_BACKTRACE -#endif // __GNUC__ +#endif +#ifdef HAVE_GCC_ABI_DEMANGLE +#define USE_DEMANGLE 1 +#else +#define USE_DEMANGLE 0 +#endif void custom_backtrace(void) { -#ifdef __GNUC__ -#ifdef HAVE_BACKTRACE +#ifdef HAVE_EXECINFO_H void *array[50]; size_t size= backtrace(array, 50); char **strings= backtrace_symbols(array, size); + if (strings == NULL) + { + return; + } + fprintf(stderr, "Number of stack frames obtained: %lu\n", (unsigned long)size); - for (size_t x= 1; x < size; x++) + char *named_function= (char *)::realloc(NULL, 1024); + + if (named_function == NULL) { - size_t sz= 200; - char *function= (char *)malloc(sz); - char *begin= 0; - char *end= 0; + ::free(strings); + return; + } - for (char *j = strings[x]; *j; ++j) + for (size_t x= 1; x < size; x++) + { + if (USE_DEMANGLE) { - if (*j == '(') { - begin = j; + size_t sz= 200; + char *named_function_ptr= (char *)::realloc(named_function, sz); + if (named_function_ptr == NULL) + { + continue; } - else if (*j == '+') { - end = j; + named_function= named_function_ptr; + + char *begin_name= 0; + char *begin_offset= 0; + char *end_offset= 0; + + for (char *j= strings[x]; *j; ++j) + { + if (*j == '(') + { + begin_name= j; + } + else if (*j == '+') + { + begin_offset= j; + } + else if (*j == ')' and begin_offset) + { + end_offset= j; + break; + } } - } - if (begin && end) - { - begin++; - *end= '\0'; - int status; - char *ret = abi::__cxa_demangle(begin, function, &sz, &status); - if (ret) + if (begin_name and begin_offset and end_offset and begin_name < begin_offset) { - function= ret; + *begin_name++= '\0'; + *begin_offset++= '\0'; + *end_offset= '\0'; + + int status; + char *ret= abi::__cxa_demangle(begin_name, named_function, &sz, &status); + if (ret) // realloc()'ed string + { + named_function= ret; + fprintf(stderr, " %s : %s()+%s\n", strings[x], begin_name, begin_offset); + } + else + { + fprintf(stderr, " %s : %s()+%s\n", strings[x], begin_name, begin_offset); + } } else { - strncpy(function, begin, sz); - strncat(function, "()", sz); - function[sz-1] = '\0'; + fprintf(stderr, " %s\n", strings[x]); } - fprintf(stderr, "%s\n", function); } else { - fprintf(stderr, "%s\n", strings[x]); + fprintf(stderr, " unmangled: %s\n", strings[x]); } - free(function); } - - free (strings); -#endif // HAVE_BACKTRACE -#endif // __GNUC__ + ::free(named_function); + ::free(strings); +#endif // HAVE_EXECINFO_H } diff --git a/libmemcached/backtrace.hpp b/libmemcached/backtrace.hpp index 98db320c..330d02c4 100644 --- a/libmemcached/backtrace.hpp +++ b/libmemcached/backtrace.hpp @@ -37,5 +37,4 @@ #pragma once -LIBMEMCACHED_LOCAL void custom_backtrace(void); diff --git a/libmemcached/behavior.cc b/libmemcached/behavior.cc index bb17f2bd..71b3f0c0 100644 --- a/libmemcached/behavior.cc +++ b/libmemcached/behavior.cc @@ -364,7 +364,9 @@ uint64_t memcached_behavior_get(memcached_st *ptr, socklen_t sock_length= sizeof(int); if (ptr->send_size != -1) // If value is -1 then we are using the default + { return (uint64_t) ptr->send_size; + } memcached_server_write_instance_st instance= memcached_server_instance_fetch(ptr, 0); diff --git a/libmemcached/flush_buffers.cc b/libmemcached/flush_buffers.cc index bb3c4dec..91d90349 100644 --- a/libmemcached/flush_buffers.cc +++ b/libmemcached/flush_buffers.cc @@ -48,7 +48,7 @@ memcached_return_t memcached_flush_buffers(memcached_st *memc) if (instance->write_buffer_offset != 0) { - if (instance->fd == -1 && + if (instance->fd == INVALID_SOCKET and (ret= memcached_connect(instance)) != MEMCACHED_SUCCESS) { WATCHPOINT_ERROR(ret); diff --git a/libmemcached/get.cc b/libmemcached/get.cc index c10f2341..25d6419d 100644 --- a/libmemcached/get.cc +++ b/libmemcached/get.cc @@ -259,7 +259,9 @@ static memcached_return_t memcached_mget_by_key_real(memcached_st *ptr, char buffer[MEMCACHED_DEFAULT_COMMAND_SIZE]; if (ptr->flags.no_block) + { (void)memcached_io_write(instance, NULL, 0, true); + } while(memcached_server_response_count(instance)) (void)memcached_response(instance, buffer, MEMCACHED_DEFAULT_COMMAND_SIZE, &ptr->result); diff --git a/libmemcached/io.cc b/libmemcached/io.cc index 10a59b68..8c8c3bc7 100644 --- a/libmemcached/io.cc +++ b/libmemcached/io.cc @@ -458,7 +458,9 @@ memcached_return_t memcached_io_read(memcached_server_write_instance_st ptr, if (ptr->fd == INVALID_SOCKET) { +#if 0 assert_msg(int(ptr->state) <= int(MEMCACHED_SERVER_STATE_ADDRINFO), "Programmer error, invalid socket state"); +#endif return MEMCACHED_CONNECTION_FAILURE; } diff --git a/libmemcached/purge.cc b/libmemcached/purge.cc index 36a33ae9..b0f864a8 100644 --- a/libmemcached/purge.cc +++ b/libmemcached/purge.cc @@ -1,4 +1,44 @@ -#include "common.h" +/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: + * + * LibMemcached + * + * Copyright (C) 2011 Data Differential, http://datadifferential.com/ + * Copyright (C) 2006-2009 Brian Aker + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * The names of its contributors may not be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT + * OWNER 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 + memcached_return_t memcached_purge(memcached_server_write_instance_st ptr) { @@ -18,7 +58,7 @@ memcached_return_t memcached_purge(memcached_server_write_instance_st ptr) so we need to be able stop any recursion.. */ memcached_set_purging(root, true); - WATCHPOINT_ASSERT(ptr->fd != -1); + WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET); /* Force a flush of the buffer to ensure that we don't have the n-1 pending requests buffered up.. */ if (memcached_io_write(ptr, NULL, 0, true) == -1) @@ -27,7 +67,7 @@ memcached_return_t memcached_purge(memcached_server_write_instance_st ptr) return memcached_set_error(*ptr, MEMCACHED_WRITE_FAILURE, MEMCACHED_AT); } - WATCHPOINT_ASSERT(ptr->fd != -1); + WATCHPOINT_ASSERT(ptr->fd != INVALID_SOCKET); uint32_t no_msg= memcached_server_response_count(ptr) - 1; if (no_msg > 0) @@ -58,7 +98,7 @@ memcached_return_t memcached_purge(memcached_server_write_instance_st ptr) * The only kind of errors I care about if is I'm out of sync with the * protocol or have problems reading data from the network.. */ - if (rc== MEMCACHED_PROTOCOL_ERROR || rc == MEMCACHED_UNKNOWN_READ_FAILURE) + if (rc== MEMCACHED_PROTOCOL_ERROR or rc == MEMCACHED_UNKNOWN_READ_FAILURE or rc == MEMCACHED_READ_FAILURE) { WATCHPOINT_ERROR(rc); ret= rc; @@ -75,7 +115,9 @@ memcached_return_t memcached_purge(memcached_server_write_instance_st ptr) { rc = (*cb.callback[y])(ptr->root, result_ptr, cb.context); if (rc != MEMCACHED_SUCCESS) + { break; + } } } } diff --git a/libmemcached/response.cc b/libmemcached/response.cc index b8d9e0b6..fc3256ba 100644 --- a/libmemcached/response.cc +++ b/libmemcached/response.cc @@ -67,10 +67,11 @@ memcached_return_t memcached_read_one_response(memcached_server_write_instance_s rc= textual_read_one_response(ptr, buffer, buffer_length, result); } - unlikely(rc == MEMCACHED_UNKNOWN_READ_FAILURE or - rc == MEMCACHED_PROTOCOL_ERROR or - rc == MEMCACHED_CLIENT_ERROR or - rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE) + if (rc == MEMCACHED_UNKNOWN_READ_FAILURE or + rc == MEMCACHED_READ_FAILURE or + rc == MEMCACHED_PROTOCOL_ERROR or + rc == MEMCACHED_CLIENT_ERROR or + rc == MEMCACHED_MEMORY_ALLOCATION_FAILURE) { memcached_io_reset(ptr); } @@ -359,7 +360,9 @@ static memcached_return_t textual_read_one_response(memcached_server_write_insta { return MEMCACHED_END; } - else if (buffer[1] == 'R' and buffer[2] == 'R' and buffer[3] == 'O' and buffer[4] == 'R') + else if (buffer[1] == 'R' and buffer[2] == 'O' and buffer[3] == 'T' and buffer[4] == 'O' and buffer[5] == 'C' and buffer[6] == 'O' and buffer[7] == 'L' + and buffer[8] == '_' + and buffer[9] == 'E' and buffer[10] == 'R' and buffer[11] == 'R' and buffer[12] == 'O' and buffer[13] == 'R') { return MEMCACHED_PROTOCOL_ERROR; } @@ -524,7 +527,7 @@ static memcached_return_t binary_read_one_response(memcached_server_write_instan case PROTOCOL_BINARY_CMD_INCREMENT: case PROTOCOL_BINARY_CMD_DECREMENT: { - if (bodylen != sizeof(uint64_t) || buffer_length != sizeof(uint64_t)) + if (bodylen != sizeof(uint64_t) or buffer_length != sizeof(uint64_t)) { return MEMCACHED_PROTOCOL_ERROR; } diff --git a/libmemcached/server.cc b/libmemcached/server.cc index 7011fd24..03426c8a 100644 --- a/libmemcached/server.cc +++ b/libmemcached/server.cc @@ -50,7 +50,7 @@ static inline void _server_init(memcached_server_st *self, memcached_st *root, self->number_of_hosts= 0; self->cursor_active= 0; self->port= port; - self->fd= -1; + self->fd= INVALID_SOCKET; self->io_bytes_sent= 0; self->server_failure_counter= 0; self->server_failure_counter_query_id= 0; @@ -88,11 +88,11 @@ static inline void _server_init(memcached_server_st *self, memcached_st *root, static memcached_server_st *_server_create(memcached_server_st *self, const memcached_st *memc) { - if (not self) + if (self == NULL) { self= libmemcached_xmalloc(memc, struct memcached_server_st); - if (not self) + if (self == NULL) { return NULL; /* MEMCACHED_MEMORY_ALLOCATION_FAILURE */ } @@ -131,13 +131,6 @@ memcached_server_st *__server_create_with(memcached_st *memc, _server_init(self, const_cast(memc), hostname, port, weight, type); - - if (memc and memcached_is_udp(memc)) - { - self->write_buffer_offset= UDP_DATAGRAM_HEADER_LENGTH; - memcached_io_init_udp_header(self, 0); - } - if (memc) { set_hostinfo(self); diff --git a/libmemcached/server_list.cc b/libmemcached/server_list.cc index d5994e85..f03dc356 100644 --- a/libmemcached/server_list.cc +++ b/libmemcached/server_list.cc @@ -83,7 +83,7 @@ memcached_server_list_append_with_weight(memcached_server_list_st ptr, memcached_string_t _hostname= { memcached_string_make_from_cstr(hostname) }; /* @todo Check return type */ - if (not __server_create_with(NULL, &new_host_list[count-1], _hostname, port, weight, port ? MEMCACHED_CONNECTION_TCP : MEMCACHED_CONNECTION_UNIX_SOCKET)) + if (__server_create_with(NULL, &new_host_list[count-1], _hostname, port, weight, port ? MEMCACHED_CONNECTION_TCP : MEMCACHED_CONNECTION_UNIX_SOCKET) == NULL) { *error= memcached_set_errno(*ptr, MEMCACHED_MEMORY_ALLOCATION_FAILURE, MEMCACHED_AT); return NULL; diff --git a/libmemcached/stats.cc b/libmemcached/stats.cc index 9b353582..3c7c1068 100644 --- a/libmemcached/stats.cc +++ b/libmemcached/stats.cc @@ -236,7 +236,7 @@ char *memcached_stat_get_value(const memcached_st *ptr, memcached_stat_st *memc_ *error= MEMCACHED_SUCCESS; - if (not memcmp("pid", key, sizeof("pid") -1)) + if (memcmp("pid", key, sizeof("pid") -1) == 0) { length= snprintf(buffer, SMALL_STRING_LEN,"%lld", (signed long long)memc_stat->pid); } diff --git a/libmemcached/storage.cc b/libmemcached/storage.cc index 89bc8e87..416b3347 100644 --- a/libmemcached/storage.cc +++ b/libmemcached/storage.cc @@ -1,14 +1,41 @@ -/* LibMemcached - * Copyright (C) 2006-2009 Brian Aker - * All rights reserved. +/* vim:expandtab:shiftwidth=2:tabstop=2:smarttab: + * + * Libmemcached library * - * Use and distribution licensed under the BSD license. See - * the COPYING file in the parent directory for full text. + * Copyright (C) 2011 Data Differential, http://datadifferential.com/ + * Copyright (C) 2006-2009 Brian Aker All rights reserved. * - * Summary: Storage related functions, aka set, replace,.. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * * The names of its contributors may not be used to endorse or + * promote products derived from this software without specific prior + * written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 THE COPYRIGHT + * OWNER 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 enum memcached_storage_action_t { diff --git a/m4/ax_cxx_gcc_abi_demangle.m4 b/m4/ax_cxx_gcc_abi_demangle.m4 new file mode 100644 index 00000000..11e8728c --- /dev/null +++ b/m4/ax_cxx_gcc_abi_demangle.m4 @@ -0,0 +1,58 @@ +# =========================================================================== +# http://www.gnu.org/software/autoconf-archive/ax_cxx_gcc_abi_demangle.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CXX_GCC_ABI_DEMANGLE +# +# DESCRIPTION +# +# If the compiler supports GCC C++ ABI name demangling (has header +# cxxabi.h and abi::__cxa_demangle() function), define +# HAVE_GCC_ABI_DEMANGLE +# +# Adapted from AX_CXX_RTTI by Luc Maisonobe +# +# LICENSE +# +# Copyright (c) 2008 Neil Ferguson +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 9 + +AC_DEFUN([AX_CXX_GCC_ABI_DEMANGLE], +[AC_CACHE_CHECK(whether the compiler supports GCC C++ ABI name demangling, +ax_cv_cxx_gcc_abi_demangle, +[AC_LANG_SAVE + AC_LANG_CPLUSPLUS + AC_TRY_COMPILE([#include +#include +#include +#include + +template +class A {}; +],[A instance; +int status = 0; +char* c_name = 0; + +c_name = abi::__cxa_demangle(typeid(instance).name(), 0, 0, &status); + +std::string name(c_name); +::free(c_name); + +return name == "A"; +], + ax_cv_cxx_gcc_abi_demangle=yes, ax_cv_cxx_gcc_abi_demangle=no) + AC_LANG_RESTORE +]) +if test "$ax_cv_cxx_gcc_abi_demangle" = yes; then + AC_DEFINE(HAVE_GCC_ABI_DEMANGLE,1, + [define if the compiler supports GCC C++ ABI name demangling]) +fi +]) diff --git a/tests/libmemcached-1.0/mem_functions.cc b/tests/libmemcached-1.0/mem_functions.cc index 40e0ee8d..2da5d046 100644 --- a/tests/libmemcached-1.0/mem_functions.cc +++ b/tests/libmemcached-1.0/mem_functions.cc @@ -95,7 +95,7 @@ using namespace libtest; #define GLOBAL_COUNT 10000 #define GLOBAL2_COUNT 100 #define SERVERS_TO_CREATE 5 -static uint32_t global_count; +static uint32_t global_count= GLOBAL2_COUNT; static pairs_st *global_pairs; static const char *global_keys[GLOBAL_COUNT]; @@ -3126,7 +3126,7 @@ static test_return_t generate_data(memcached_st *memc) { unsigned int check_execute= execute_set(memc, global_pairs, global_count); - test_compare(check_execute, global_count); + test_compare(global_count, check_execute); return TEST_SUCCESS; } -- 2.30.2