--- /dev/null
+/*
+ * Copyright 2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "folly/Demangle.h"
+
+#include <algorithm>
+#include <string.h>
+
+#include "folly/Malloc.h"
+
+#if FOLLY_HAVE_CPLUS_DEMANGLE_V3_CALLBACK
+# include <cxxabi.h>
+
+// From libiberty
+//
+// TODO(tudorb): Detect this with autoconf for the open-source version.
+//
+// __attribute__((weak)) doesn't work, because cplus_demangle_v3_callback
+// is exported by an object file in libiberty.a, and the ELF spec says
+// "The link editor does not extract archive members to resolve undefined weak
+// symbols" (but, interestingly enough, will resolve undefined weak symbols
+// with definitions from archive members that were extracted in order to
+// resolve an undefined global (strong) symbol)
+
+# ifndef DMGL_NO_OPTS
+# define FOLLY_DEFINED_DMGL 1
+# define DMGL_NO_OPTS 0 /* For readability... */
+# define DMGL_PARAMS (1 << 0) /* Include function args */
+# define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
+# define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */
+# define DMGL_VERBOSE (1 << 3) /* Include implementation details. */
+# define DMGL_TYPES (1 << 4) /* Also try to demangle type encodings. */
+# define DMGL_RET_POSTFIX (1 << 5) /* Print function return types (when
+ present) after function signature */
+# endif
+
+extern "C" int cplus_demangle_v3_callback(
+ const char* mangled,
+ int options, // We use DMGL_PARAMS | DMGL_TYPES, aka 0x11
+ void (*callback)(const char*, size_t, void*),
+ void* arg);
+
+#endif
+
+namespace {
+
+// glibc doesn't have strlcpy
+size_t my_strlcpy(char* dest, const char* src, size_t size) {
+ size_t len = strlen(src);
+ if (size != 0) {
+ size_t n = std::min(len, size - 1); // always null terminate!
+ memcpy(dest, src, n);
+ dest[n] = '\0';
+ }
+ return len;
+}
+
+} // namespace
+
+namespace folly {
+
+#if FOLLY_HAVE_CPLUS_DEMANGLE_V3_CALLBACK
+
+fbstring demangle(const char* name) {
+ int status;
+ size_t len = 0;
+ // malloc() memory for the demangled type name
+ char* demangled = abi::__cxa_demangle(name, nullptr, &len, &status);
+ if (status != 0) {
+ return name;
+ }
+ // len is the length of the buffer (including NUL terminator and maybe
+ // other junk)
+ return fbstring(demangled, strlen(demangled), len, AcquireMallocatedString());
+}
+
+namespace {
+
+struct DemangleBuf {
+ char* dest;
+ size_t remaining;
+ size_t total;
+};
+
+void demangleCallback(const char* str, size_t size, void* p) {
+ DemangleBuf* buf = static_cast<DemangleBuf*>(p);
+ size_t n = std::min(buf->remaining, size);
+ memcpy(buf->dest, str, n);
+ buf->dest += n;
+ buf->remaining -= n;
+ buf->total += size;
+}
+
+} // namespace
+
+size_t demangle(const char* name, char* out, size_t outSize) {
+ DemangleBuf dbuf;
+ dbuf.dest = out;
+ dbuf.remaining = outSize ? outSize - 1 : 0; // leave room for null term
+ dbuf.total = 0;
+
+ // Unlike most library functions, this returns 1 on success and 0 on failure
+ int status = cplus_demangle_v3_callback(
+ name,
+ DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES,
+ demangleCallback,
+ &dbuf);
+ if (status == 0) { // failed, return original
+ return my_strlcpy(out, name, outSize);
+ }
+ if (outSize != 0) {
+ *dbuf.dest = '\0';
+ }
+ return dbuf.total;
+}
+
+#else
+
+fbstring demangle(const char* name) {
+ return name;
+}
+
+size_t demangle(const char* name, char* out, size_t outSize) {
+ return my_strlcpy(out, name, outSize);
+}
+
+#endif
+
+} // folly
--- /dev/null
+/*
+ * Copyright 2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include "folly/FBString.h"
+
+namespace folly {
+
+/**
+ * Return the demangled (prettyfied) version of a C++ type.
+ *
+ * This function tries to produce a human-readable type, but the type name will
+ * be returned unchanged in case of error or if demangling isn't supported on
+ * your system.
+ *
+ * Use for debugging -- do not rely on demangle() returning anything useful.
+ *
+ * This function may allocate memory (and therefore throw std::bad_alloc).
+ */
+fbstring demangle(const char* name);
+inline fbstring demangle(const std::type_info& type) {
+ return demangle(type.name());
+}
+
+/**
+ * Return the demangled (prettyfied) version of a C++ type in a user-provided
+ * buffer.
+ *
+ * The semantics are the same as for snprintf or strlcpy: bufSize is the size
+ * of the buffer, the string is always null-terminated, and the return value is
+ * the number of characters (not including the null terminator) that would have
+ * been written if the buffer was big enough. (So a return value >= bufSize
+ * indicates that the output was truncated)
+ *
+ * This function does not allocate memory and is async-signal-safe.
+ *
+ * Note that the underlying function for the fbstring-returning demangle is
+ * somewhat standard (abi::__cxa_demangle, which uses malloc), the underlying
+ * function for this version is less so (cplus_demangle_v3_callback from
+ * libiberty), so it is possible for the fbstring version to work, while this
+ * version returns the original, mangled name.
+ */
+size_t demangle(const char* name, char* buf, size_t bufSize);
+inline size_t demangle(const std::type_info& type, char* buf, size_t bufSize) {
+ return demangle(type.name(), buf, bufSize);
+}
+
+}
Benchmark.cpp \
Bits.cpp \
Conv.cpp \
+ Demangle.cpp \
detail/CacheLocality.cpp \
dynamic.cpp \
EscapeTables.cpp \
#include <iterator>
#include <glog/logging.h>
-#if FOLLY_HAVE_CPLUS_DEMANGLE_V3_CALLBACK
-# include <cxxabi.h>
-
-// From libiberty
-//
-// TODO(tudorb): Detect this with autoconf for the open-source version.
-//
-// __attribute__((weak)) doesn't work, because cplus_demangle_v3_callback
-// is exported by an object file in libiberty.a, and the ELF spec says
-// "The link editor does not extract archive members to resolve undefined weak
-// symbols" (but, interestingly enough, will resolve undefined weak symbols
-// with definitions from archive members that were extracted in order to
-// resolve an undefined global (strong) symbol)
-
-# ifndef DMGL_NO_OPTS
-# define FOLLY_DEFINED_DMGL 1
-# define DMGL_NO_OPTS 0 /* For readability... */
-# define DMGL_PARAMS (1 << 0) /* Include function args */
-# define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */
-# define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */
-# define DMGL_VERBOSE (1 << 3) /* Include implementation details. */
-# define DMGL_TYPES (1 << 4) /* Also try to demangle type encodings. */
-# define DMGL_RET_POSTFIX (1 << 5) /* Print function return types (when
- present) after function signature */
-# endif
-
-extern "C" int cplus_demangle_v3_callback(
- const char* mangled,
- int options, // We use DMGL_PARAMS | DMGL_TYPES, aka 0x11
- void (*callback)(const char*, size_t, void*),
- void* arg);
-
-#endif
-
namespace folly {
namespace {
return result;
}
-namespace {
-
-// glibc doesn't have strlcpy
-size_t my_strlcpy(char* dest, const char* src, size_t size) {
- size_t len = strlen(src);
- if (size != 0) {
- size_t n = std::min(len, size - 1); // always null terminate!
- memcpy(dest, src, n);
- dest[n] = '\0';
- }
- return len;
-}
-
-} // namespace
-
-#if FOLLY_HAVE_CPLUS_DEMANGLE_V3_CALLBACK
-
-fbstring demangle(const char* name) {
- int status;
- size_t len = 0;
- // malloc() memory for the demangled type name
- char* demangled = abi::__cxa_demangle(name, nullptr, &len, &status);
- if (status != 0) {
- return name;
- }
- // len is the length of the buffer (including NUL terminator and maybe
- // other junk)
- return fbstring(demangled, strlen(demangled), len, AcquireMallocatedString());
-}
-
-namespace {
-
-struct DemangleBuf {
- char* dest;
- size_t remaining;
- size_t total;
-};
-
-void demangleCallback(const char* str, size_t size, void* p) {
- DemangleBuf* buf = static_cast<DemangleBuf*>(p);
- size_t n = std::min(buf->remaining, size);
- memcpy(buf->dest, str, n);
- buf->dest += n;
- buf->remaining -= n;
- buf->total += size;
-}
-
-} // namespace
-
-size_t demangle(const char* name, char* out, size_t outSize) {
- DemangleBuf dbuf;
- dbuf.dest = out;
- dbuf.remaining = outSize ? outSize - 1 : 0; // leave room for null term
- dbuf.total = 0;
-
- // Unlike most library functions, this returns 1 on success and 0 on failure
- int status = cplus_demangle_v3_callback(
- name,
- DMGL_PARAMS | DMGL_ANSI | DMGL_TYPES,
- demangleCallback,
- &dbuf);
- if (status == 0) { // failed, return original
- return my_strlcpy(out, name, outSize);
- }
- if (outSize != 0) {
- *dbuf.dest = '\0';
- }
- return dbuf.total;
-}
-
-#else
-
-fbstring demangle(const char* name) {
- return name;
-}
-
-size_t demangle(const char* name, char* out, size_t outSize) {
- return my_strlcpy(out, name, outSize);
-}
-
-#endif
-
namespace detail {
size_t hexDumpLine(const void* ptr, size_t offset, size_t size,
#include <unordered_map>
#include "folly/Conv.h"
+#include "folly/Demangle.h"
#include "folly/FBString.h"
#include "folly/FBVector.h"
#include "folly/Portability.h"
*/
fbstring errnoStr(int err);
-/**
- * Return the demangled (prettyfied) version of a C++ type.
- *
- * This function tries to produce a human-readable type, but the type name will
- * be returned unchanged in case of error or if demangling isn't supported on
- * your system.
- *
- * Use for debugging -- do not rely on demangle() returning anything useful.
- *
- * This function may allocate memory (and therefore throw std::bad_alloc).
- */
-fbstring demangle(const char* name);
-inline fbstring demangle(const std::type_info& type) {
- return demangle(type.name());
-}
-
-/**
- * Return the demangled (prettyfied) version of a C++ type in a user-provided
- * buffer.
- *
- * The semantics are the same as for snprintf or strlcpy: bufSize is the size
- * of the buffer, the string is always null-terminated, and the return value is
- * the number of characters (not including the null terminator) that would have
- * been written if the buffer was big enough. (So a return value >= bufSize
- * indicates that the output was truncated)
- *
- * This function does not allocate memory and is async-signal-safe.
- *
- * Note that the underlying function for the fbstring-returning demangle is
- * somewhat standard (abi::__cxa_demangle, which uses malloc), the underlying
- * function for this version is less so (cplus_demangle_v3_callback from
- * libiberty), so it is possible for the fbstring version to work, while this
- * version returns the original, mangled name.
- */
-size_t demangle(const char* name, char* buf, size_t bufSize);
-inline size_t demangle(const std::type_info& type, char* buf, size_t bufSize) {
- return demangle(type.name(), buf, bufSize);
-}
-
/**
* Debug string for an exception: include type and what().
*/