Skip to content

Commit

Permalink
common/BackTrace: add operator<<
Browse files Browse the repository at this point in the history
replace BackTrace::print() with the operator<< where the former is used.

Signed-off-by: Kefu Chai <kchai@redhat.com>
  • Loading branch information
tchaikov committed Jan 15, 2017
1 parent 5c98ac8 commit 74025ef
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/common/BackTrace.cc
Expand Up @@ -14,7 +14,7 @@

namespace ceph {

void BackTrace::print(std::ostream& out)
void BackTrace::print(std::ostream& out) const
{
out << " " << pretty_version_to_str() << std::endl;
for (size_t i = skip; i < size; i++) {
Expand Down
7 changes: 6 additions & 1 deletion src/common/BackTrace.h
Expand Up @@ -35,9 +35,14 @@ struct BackTrace {
BackTrace(const BackTrace& other);
const BackTrace& operator=(const BackTrace& other);

void print(std::ostream& out);
void print(std::ostream& out) const;
};

inline std::ostream& operator<<(std::ostream& out, const BackTrace& bt) {
bt.print(out);
return out;
}

}

#endif
9 changes: 4 additions & 5 deletions src/common/assert.cc
Expand Up @@ -50,7 +50,6 @@ namespace ceph {
tss << ceph_clock_now();

char buf[8096];
BackTrace *bt = new BackTrace(1);
snprintf(buf, sizeof(buf),
"%s: In function '%s' thread %llx time %s\n"
"%s: %d: FAILED assert(%s)\n",
Expand All @@ -60,15 +59,15 @@ namespace ceph {

// TODO: get rid of this memory allocation.
ostringstream oss;
bt->print(oss);
oss << BackTrace(1);
dout_emergency(oss.str());

dout_emergency(" NOTE: a copy of the executable, or `objdump -rdS <executable>` "
"is needed to interpret this.\n");

if (g_assert_context) {
lderr(g_assert_context) << buf << std::endl;
bt->print(*_dout);
*_dout << oss.str();
*_dout << " NOTE: a copy of the executable, or `objdump -rdS <executable>` "
<< "is needed to interpret this.\n" << dendl;

Expand Down Expand Up @@ -130,15 +129,15 @@ namespace ceph {

// TODO: get rid of this memory allocation.
ostringstream oss;
bt->print(oss);
oss << *bt;
dout_emergency(oss.str());

dout_emergency(" NOTE: a copy of the executable, or `objdump -rdS <executable>` "
"is needed to interpret this.\n");

if (g_assert_context) {
lderr(g_assert_context) << buf << std::endl;
bt->print(*_dout);
*_dout << oss.str();
*_dout << " NOTE: a copy of the executable, or `objdump -rdS <executable>` "
<< "is needed to interpret this.\n" << dendl;

Expand Down
3 changes: 1 addition & 2 deletions src/common/cmdparse.cc
Expand Up @@ -329,9 +329,8 @@ handle_bad_get(CephContext *cct, string k, const char *tname)
errstr << "bad boost::get: key " << k << " is not type " << typestr;
lderr(cct) << errstr.str() << dendl;

BackTrace bt(1);
ostringstream oss;
bt.print(oss);
oss << BackTrace(1);
lderr(cct) << oss.rdbuf() << dendl;
if (status == 0)
free((char *)typestr);
Expand Down
2 changes: 1 addition & 1 deletion src/common/lockdep.cc
Expand Up @@ -129,7 +129,7 @@ int lockdep_dump_locks()
++q) {
lockdep_dout(0) << " * " << lock_names[q->first] << "\n";
if (q->second)
q->second->print(*_dout);
*_dout << *(q->second);
*_dout << dendl;
}
}
Expand Down
8 changes: 8 additions & 0 deletions src/test/common/CMakeLists.txt
Expand Up @@ -217,3 +217,11 @@ add_executable(unittest_dns_resolve
target_link_libraries(unittest_dns_resolve global)
add_ceph_unittest(unittest_dns_resolve
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unittest_dns_resolve)

add_executable(unittest_back_trace
test_back_trace.cc)
set_source_files_properties(test_back_trace.cc PROPERTIES
COMPILE_FLAGS -fno-inline)
target_link_libraries(unittest_back_trace ceph-common)
add_ceph_unittest(unittest_back_trace
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unittest_back_trace)
41 changes: 41 additions & 0 deletions src/test/common/test_back_trace.cc
@@ -0,0 +1,41 @@
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab

#include <boost/algorithm/string.hpp>
// std::regex support in libstdc++ 4.8 is incomplete, so let's stick to
// boost::regex now.
#include <boost/regex.hpp>
#include <gtest/gtest.h>
#include <sstream>
#include <string>

#include "common/BackTrace.h"
#include "common/version.h"

// a dummy function, so we can check "foo" in the backtrace.
// do not mark this function as static or put it into an anonymous namespace,
// otherwise it's function name will be removed in the backtrace.
std::string foo()
{
std::ostringstream oss;
oss << ceph::BackTrace(1);
return oss.str();
}

// a typical backtrace looks like:
//
// ceph version Development (no_version)
// 1: (foo[abi:cxx11]()+0x4a) [0x5562231cf22a]
// 2: (BackTrace_Basic_Test::TestBody()+0x28) [0x5562231cf2fc]
TEST(BackTrace, Basic) {
std::string bt = foo();
std::vector<std::string> lines;
boost::split(lines, bt, boost::is_any_of("\n"));
const unsigned lineno = 1;
ASSERT_GT(lines.size(), lineno);
ASSERT_EQ(lines[0].find(pretty_version_to_str()), 1);
boost::regex e{"^ 1: "
"\\(foo.*\\)\\s"
"\\[0x[[:xdigit:]]+\\]$"};
EXPECT_TRUE(boost::regex_match(lines[lineno], e));
}

0 comments on commit 74025ef

Please sign in to comment.