Skip to content

Commit c1319a2

Browse files
committed
Several changes:
- Merges from master: - Make WPopupMenu pop up above other popups - Added support for using libunwind to print stacktraces
1 parent bd81934 commit c1319a2

20 files changed

+252
-23
lines changed

CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ OPTION(WT_NO_STD_LOCALE "Build Wt to run on a system without std::locale support
115115
OPTION(WT_NO_STD_WSTRING "Build Wt to run on a system without std::wstring support" OFF)
116116
OPTION(ENABLE_OPENGL "Build Wt with support for server-side opengl rendering" ON)
117117
OPTION(WT_WARN_HEADER_MISSING_H "Output a warning if a Wt header without .h extension is included (deprecated since Wt 4.0.0)" ON)
118+
OPTION(ENABLE_UNWIND "Build Wt with stacktrace support using libunwind" OFF)
118119

119120
IF(NOT CMAKE_CXX_STANDARD)
120121
SET(CMAKE_CXX_STANDARD 11)
@@ -290,6 +291,8 @@ SET(SKIA_PREFIX ${USERLIB_PREFIX} CACHE PATH
290291
"Prefix of skia library (overrides USERLIB_PREFIX)")
291292
SET(ASIO_PREFIX ${USERLIB_PREFIX} CACHE PATH
292293
"Prefix of Asio (overrides USERLIB_PREFIX), only used when WT_ASIO_IMPLEMENTATION is standalone")
294+
SET(UNWIND_PREFIX ${UNWIND_PREFIX} CACHE PATH
295+
"Prefix of unwind library (overrides USERLIB_PREFIX)")
293296

294297
OPTION(DEBUG "Support for debugging, must be enabled also in wt_config.xml" OFF)
295298

@@ -338,6 +341,10 @@ INCLUDE(cmake/WtFindGm.txt)
338341
INCLUDE(cmake/WtFindGL.txt)
339342
INCLUDE(cmake/WtFindSkia.txt)
340343

344+
IF (ENABLE_UNWIND)
345+
INCLUDE(cmake/WtFindUnwind.txt)
346+
ENDIF (ENABLE_UNWIND)
347+
341348
IF (ENABLE_PANGO)
342349
INCLUDE(cmake/WtFindPangoFt2.txt)
343350
ENDIF (ENABLE_PANGO)
@@ -615,6 +622,10 @@ IF(ENABLE_OPENGL AND GL_FOUND AND WT_HAS_WRASTERIMAGE)
615622
SET(HAVE_GL TRUE)
616623
ENDIF(ENABLE_OPENGL AND GL_FOUND AND WT_HAS_WRASTERIMAGE)
617624

625+
IF(ENABLE_UNWIND AND UNWIND_FOUND)
626+
SET(HAVE_UNWIND ON)
627+
ENDIF(ENABLE_UNWIND AND UNWIND_FOUND)
628+
618629
# Compile time constants & make sure our build finds it
619630
FILE(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Wt)
620631
SET(WCONFIG_H_PATH ${CMAKE_CURRENT_BINARY_DIR}/Wt/WConfig.h)

cmake/WtFindUnwind.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
FIND_PATH(UNWIND_INCLUDE libunwind.h
2+
${UNWIND_PREFIX}/include
3+
/usr/include
4+
)
5+
6+
FIND_LIBRARY(UNWIND_LIB
7+
NAMES
8+
unwind
9+
PATHS
10+
${UNWIND_PREFIX}/lib
11+
/usr/lib
12+
)
13+
14+
IF(UNWIND_INCLUDE AND UNWIND_LIB)
15+
SET(UNWIND_FOUND TRUE)
16+
SET(UNWIND_INCLUDE_DIRS ${UNWIND_INCLUDE})
17+
SET(UNWIND_LIBRARIES ${UNWIND_LIB})
18+
ELSE(UNWIND_INCLUDE AND UNWIND_LIB)
19+
SET(UNWIND_FOUND FALSE)
20+
ENDIF(UNWIND_INCLUDE AND UNWIND_LIB)

src/CMakeLists.txt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,17 @@ ELSEIF(WT_FONTSUPPORT_DIRECTWRITE)
579579
MESSAGE("** Enabling advanced font support using DirectWrite")
580580
ENDIF(WT_FONTSUPPORT_SIMPLE)
581581

582+
IF(HAVE_UNWIND)
583+
ADD_DEFINITIONS(-DWT_WITH_UNWIND)
584+
TARGET_LINK_LIBRARIES(wt PRIVATE ${UNWIND_LIBRARIES})
585+
INCLUDE_DIRECTORIES(${UNWIND_INCLUDE_DIRS})
586+
MESSAGE("** Enabling stacktrace prints using libunwind")
587+
ELSE(HAVE_UNWIND)
588+
IF(ENABLE_UNWIND)
589+
MESSAGE("** Disabling stacktrace prints: could not find libunwind")
590+
ENDIF(ENABLE_UNWIND)
591+
ENDIF(HAVE_UNWIND)
592+
582593
IF(MULTI_THREADED_BUILD)
583594
TARGET_LINK_LIBRARIES(wt PRIVATE ${CMAKE_THREAD_LIBS_INIT})
584595
ENDIF(MULTI_THREADED_BUILD)

src/Wt/Auth/Dbo/UserDatabase

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#include <Wt/Auth/AbstractUserDatabase.h>
1111
#include <Wt/Auth/AuthService.h>
1212
#include <Wt/Auth/Dbo/AuthInfo.h>
13+
#include <Wt/WException.h>
1314
#include <Wt/WLogger.h>
1415

1516
namespace Wt {
@@ -298,7 +299,7 @@ public:
298299
if (session_.find<AuthTokenType>().where("\"value\" = ?")
299300
.bind(token.hash())
300301
.resultList().size() > 0)
301-
throw std::runtime_error("Token hash collision");
302+
throw WException("Token hash collision");
302303

303304
/*
304305
* Prevent a user from piling up the database with tokens

src/Wt/Auth/HashFunction.C

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,12 @@ std::string BCryptHashFunction::compute(const std::string& msg,
100100

101101
if (!crypt_gensalt_rn("$2y$", count_, c_salt, 16, setting, 32)) {
102102
std::perror("crypt_gen_salt_rn");
103-
throw std::runtime_error("bcrypt() gensalt internal error");
103+
throw WException("bcrypt() gensalt internal error");
104104
} else {
105105
char result[64];
106106
if (!crypt_rn(msg.c_str(), setting, result, 64)) {
107107
std::perror("crypt_rn");
108-
throw std::runtime_error("bcrypt() internal error");
108+
throw WException("bcrypt() internal error");
109109
}
110110
return result;
111111
}
@@ -119,7 +119,7 @@ bool BCryptHashFunction::verify(const std::string& msg,
119119

120120
if (!crypt_rn(msg.c_str(), hash.c_str(), result, 64)) {
121121
std::perror("crypt_rn");
122-
throw std::runtime_error("bcrypt() internal error");
122+
throw WException("bcrypt() internal error");
123123
}
124124

125125
return result == hash;

src/Wt/Dbo/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ IF(ENABLE_LIBWTDBO)
3131
StringStream.C
3232
)
3333

34+
IF(HAVE_UNWIND)
35+
TARGET_LINK_LIBRARIES(wtdbo PRIVATE ${UNWIND_LIBRARIES})
36+
ENDIF(HAVE_UNWIND)
37+
3438
IF(MSVC)
3539
#win32 links automatically against boost libs; specifying too much causes
3640
#trouble

src/Wt/Dbo/Exception

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
namespace Wt {
1515
namespace Dbo {
1616

17+
extern WTDBO_API std::string backtrace();
18+
1719
/*! \class Exception Wt/Dbo/Exception.h Wt/Dbo/Exception.h
1820
* \brief %Exception base class for %Wt::%Dbo.
1921
*

src/Wt/Dbo/Exception.C

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,86 @@
66

77
#include "Wt/Dbo/Exception.h"
88

9+
#ifdef WT_WITH_UNWIND
10+
#define UNW_LOCAL_ONLY
11+
12+
#include <cxxabi.h>
13+
#include <libunwind.h>
14+
#include <cstdio>
15+
#include <cstdlib>
16+
17+
namespace Wt {
18+
namespace Dbo {
19+
20+
std::string backtrace() {
21+
unw_cursor_t cursor;
22+
unw_context_t context;
23+
24+
// Initialize cursor to current frame for local unwinding.
25+
unw_getcontext(&context);
26+
unw_init_local(&cursor, &context);
27+
28+
std::stringstream ss;
29+
30+
// Unwind frames one by one, going up the frame stack.
31+
while (unw_step(&cursor) > 0) {
32+
unw_word_t offset, pc;
33+
unw_get_reg(&cursor, UNW_REG_IP, &pc);
34+
if (pc == 0) {
35+
break;
36+
}
37+
38+
ss << "0x" << std::hex << pc;
39+
40+
char sym[256];
41+
if (unw_get_proc_name(&cursor, sym, sizeof(sym), &offset) == 0) {
42+
char* nameptr = sym;
43+
int status;
44+
char* demangled = abi::__cxa_demangle(sym, nullptr, nullptr, &status);
45+
if (status == 0) {
46+
nameptr = demangled;
47+
}
48+
49+
ss << " (" << nameptr << "+0x" << std::hex << offset << ")" << std::endl;
50+
51+
std::free(demangled);
52+
} else {
53+
ss << " -- error: unable to obtain symbol name for this frame" << std::endl;
54+
}
55+
}
56+
57+
return ss.str();
58+
}
59+
60+
}
61+
}
62+
63+
#else
64+
65+
namespace Wt {
66+
namespace Dbo {
67+
68+
std::string backtrace() {
69+
return "N/A";
70+
}
71+
72+
}
73+
}
74+
75+
#endif
76+
977
namespace Wt {
1078
namespace Dbo {
1179

1280
Exception::Exception(const std::string& error, const std::string& code)
81+
#ifdef WT_WITH_UNWIND
82+
: std::runtime_error(error + " at\n" + backtrace()),
83+
#else
1384
: std::runtime_error(error),
85+
#endif
1486
code_(code)
15-
{ }
87+
{
88+
}
1689

1790
Exception::~Exception() throw() { }
1891

src/Wt/Dbo/QueryModel_impl.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,6 @@ void QueryModel<Result>::cacheRow(int row) const
286286

287287
Transaction transaction(query_.session());
288288

289-
std::cerr << "Fetching offset=" << qOffset << ", limit=" << qLimit << std::endl;
290289
collection<Result> results = query_.resultList();
291290
cache_.clear();
292291
cache_.insert(cache_.end(), results.begin(), results.end());

src/Wt/Dbo/Transaction.C

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ Transaction::~Transaction() noexcept(false)
5454
if (impl_->transactionCount_ == 1)
5555
rollback();
5656
} catch (...) {
57-
std::cerr << "Unexpected transaction during Transaction::rollback()"
57+
std::cerr << "Unexpected exception during Transaction::rollback()"
5858
<< std::endl;
5959
}
6060

0 commit comments

Comments
 (0)