Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bugfix/3169 stack fix #3182

Merged
merged 20 commits into from Dec 14, 2018
Merged
Show file tree
Hide file tree
Changes from 17 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
c32bcd0
reffs #3169 initial new stack handling
davidnich Dec 10, 2018
4cb631c
refs #3169 progress on unified thread and exception stack trace support
davidnich Dec 11, 2018
59a60ee
reffs #3169 removed lots of old code related to the old optional call…
davidnich Dec 11, 2018
7259e1a
Merge remote-tracking branch 'origin/develop' into bugfix/3169_stack_fix
davidnich Dec 12, 2018
9988ea3
refs #3169 fixed deadlock in thread stack retrieval
davidnich Dec 12, 2018
7e546d7
refs #3169 new stack trace API updates
davidnich Dec 13, 2018
1871a80
refs #3177 fixed binary module installation with autotools
davidnich Dec 12, 2018
fbf1e2c
refs #3179 std::string COW issue workaround (#3180)
davidnich Dec 13, 2018
4f565d3
reffs #3169 removed lots of old code related to the old optional call…
davidnich Dec 11, 2018
a7358a3
refs #3169 new stack trace API updates
davidnich Dec 13, 2018
330a512
refs #3169 finalized the API and fixed C++ issues
davidnich Dec 13, 2018
8f4e2b5
Merge branch 'develop' into bugfix/3169_stack_fix
davidnich Dec 13, 2018
d7a9902
refs #3169 refactored default exception handling & warning output, ad…
davidnich Dec 14, 2018
5172049
refs #3169 fixed test
davidnich Dec 14, 2018
c0af588
refs #3169 more API updates
davidnich Dec 14, 2018
5f2c10b
refs #3169 fixed dbg stmt
davidnich Dec 14, 2018
a74d9ac
refs #3169 show builtin code location properly in call & exception st…
davidnich Dec 14, 2018
bed7b11
reffs #3169 updated from review comments
davidnich Dec 14, 2018
5cd8d36
reffs #3169 updated from review feedback
davidnich Dec 14, 2018
915e38a
Merge branch 'develop' into bugfix/3169_stack_fix
davidnich Dec 14, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 0 additions & 9 deletions CMakeLists.txt
Expand Up @@ -6,10 +6,6 @@ option(ICONV_TRANSLIT
"Force //Translit to iconv encoding to do transliteration, if OFF it is tested for"
OFF)

option(QORE_RUNTIME_THREAD_STACK_TRACE
"enable runtime thread stack trace (turning off breaks compatibility)"
ON)

set(VERSION_MAJOR 0)
set(VERSION_MINOR 9)
set(VERSION_SUB 0)
Expand Down Expand Up @@ -37,10 +33,6 @@ else ()
add_definitions(-DNDEBUG)
endif ()

#if ((NOT ${QORE_BUILD_TYPE_LWR} MATCHES "debug") AND QORE_RUNTIME_THREAD_STACK_TRACE)
# message(FATAL_ERROR "QORE_RUNTIME_THREAD_STACK_TRACE only available on debug builds")
#endif()

# simulate QoreConfig
set(QORE_QDX_EXECUTABLE "${CMAKE_SOURCE_DIR}/doxygen/qdx")
# simulate QoreConfig
Expand Down Expand Up @@ -491,7 +483,6 @@ set(LIBQORE_CPP_SRC
lib/QoreSQLStatement.cpp
lib/ExecArgList.cpp
lib/CallReferenceNode.cpp
lib/CallStack.cpp
lib/NamedScope.cpp
lib/RWLock.cpp
lib/QoreSSLBase.cpp
Expand Down
15 changes: 0 additions & 15 deletions configure.ac
Expand Up @@ -1308,20 +1308,6 @@ if test "$enable_optimization" = "auto"; then
fi
fi

AC_ARG_ENABLE([runtime-thread-stack-trace],
[AS_HELP_STRING([--enable-runtime-thread-stack-trace],
[enable runtime thread stack trace (performance penalty, default: off)])],
[case "${enable_runtime_thread_stack_trace}" in
yes|no) ;;
*) AC_MSG_ERROR(bad value ${enable_runtime_thread_stack_trace} for --enable-runtime-thread-stack-trace) ;;
esac],
[enable_runtime_thread_stack_trace=yes])

if test "${enable_runtime_thread_stack_trace}" = "yes" -o "${enable_debug}" = yes; then
AC_DEFINE(QORE_RUNTIME_THREAD_STACK_TRACE, 1, [to enable runtime thread stack tracing, needed for getAllThreadCallStacks()])
enable_runtime_thread_stack_trace=yes
fi

# check for gcc visibility support
AC_MSG_CHECKING([for gcc visibility support])
if test "$GXX" = "yes"; then
Expand Down Expand Up @@ -1878,7 +1864,6 @@ AM_CONDITIONAL([COND_PROFILE], [test "$enable_profile" = yes])
AM_CONDITIONAL([COND_SINGLE_COMPILATION_UNIT], [test "$enable_single_compilation_unit" = yes])
AM_CONDITIONAL([COND_MACOSX], [test "$darwin" = yes])
AM_CONDITIONAL([COND_DOXYGEN], [test -n "$with_doxygen"])
AM_CONDITIONAL([COND_STACK_TRACE], [test "$enable_runtime_thread_stack_trace" = yes])
AM_CONDITIONAL([COND_SOLARIS_CC_X86_64], [test "$solaris_cc_x86_64" = yes])
AM_CONDITIONAL([COND_SOLARIS_CC_I386], [test "$solaris_cc_i386" = yes])
AM_CONDITIONAL([COND_SOLARIS_CC_SPARC32], [test "$solaris_cc_sparc32" = yes])
Expand Down
15 changes: 14 additions & 1 deletion doxygen/lang/900_release_notes.dox.tmpl
Expand Up @@ -89,13 +89,20 @@
- @ref Qore::set_default_thread_stack_size() "set_default_thread_stack_size()"
- @ref Qore::set_module_option() "set_module_option()"
- @ref Qore::set_thread_name() "set_thread_name()"
- Updated functions:
- @ref Qore::get_ex_pos() "get_ex_pos()": \c lang info was added to the result string if available
- New modules:
- <a href="../../modules/FsUtil/html/index.html">FsUtil</a>
- <a href="../../modules/Logger/html/index.html">Logger</a>
- <a href="../../modules/reflection/html/index.html">reflection</a>
- New and updated hashdecls:
- @ref Qore::NetIfInfo "NetIfInfo": new @ref hashdecl "hashdecl" for the @ref Qore::get_netif_list() "get_netif_list()" function
- @ref Qore::CallStackInfo "CallStackInfo": updated with new members: \c programid and \c statementid
- @ref Qore::CallStackInfo "CallStackInfo": updated with new members:
- \c lang
- \c programid
- \c statementid
- @ref Qore::ExceptionInfo "ExceptionInfo": updated with a new member:
- \c lang
- New constants:
- @ref Qore::DomainCodeMap "DomainCodeMap"
- @ref Qore::DomainStringMap "DomainStringMap"
Expand Down Expand Up @@ -171,6 +178,8 @@
- Updated \c parse_to_qore_value() to support single-element lists and hashes with curly brackets including
empty hashes
(<a href="https://github.com/qorelanguage/qore/issues/3138">issue 3138</a>)
- updated @ref Util::get_exception_string() "get_exception_string()" to show the \c lang value
(<a href="https://github.com/qorelanguage/qore/issues/3182">issue 3182</a>)
- <a href="../../modules/CsvUtil/html/index.html">CsvUtil</a> module updates:
- Added public methods \c AbstractCsvIterator::getRawLine() and \c AbstractCsvIterator::getRawLineValues() (<a href="https://github.com/qorelanguage/qore/issues/2739">issue 2739</a>)
- <a href="../../modules/Swagger/html/index.html">Swagger</a>:
Expand All @@ -187,6 +196,10 @@
- <a href="../../modules/DebugHandler/html/index.html">DebugHandler</a> reimplemented to support multiple websocket handlers
- Programs are not interrupted in bootstrap code
- Command line utils display source line code when interrupted
- Runtime thread stack traces are available in all builds and the
@ref Qore::Option::HAVE_RUNTIME_THREAD_STACK_TRACE "HAVE_RUNTIME_THREAD_STACK_TRACE" constant is always
@ref True "True". Furthermore, the %Qore library has been extended to support stack tracing when embedding
or integrating code in other programming languages at runtime

@subsection qore_09_bug_fixes Bug Fixes in Qore
- worked around a potential COW bug in \c std::string in GNU libdstdc++ 6+
Expand Down
31 changes: 31 additions & 0 deletions examples/test/qlib/Util/get_exception_string.qtest
@@ -0,0 +1,31 @@
#!/usr/bin/env qore
# -*- mode: qore; indent-tabs-mode: nil -*-

%new-style
%enable-all-warnings
%require-types
%strict-args

%requires ../../../../qlib/Util.qm
%requires ../../../../qlib/QUnit.qm

%exec-class GetExceptionString

public class GetExceptionString inherits QUnit::Test {
constructor() : Test("GetExceptionString", "1.0") {
addTestCase("get_exception_string()", \testGetExceptionString());

set_return_value(main());
}

testGetExceptionString() {
hash<ExceptionInfo> ex;
try {
throw "ERR", "err";
} catch (hash<ExceptionInfo> ex1) {
ex = ex1;
}
assertEq("Qore", ex.callstack[0].lang);
assertEq("GetExceptionString::constructor", ex.callstack.last().function);
}
}
9 changes: 6 additions & 3 deletions examples/test/qore/classes/Program/program-vars.qtest
Expand Up @@ -6,7 +6,7 @@
%require-types
%strict-args
%no-child-restrictions
%no-debugging
%no-debugging

%requires QUnit

Expand Down Expand Up @@ -58,7 +58,7 @@ class ProgramVarsTest inherits QUnit::Test {
"endline": 1,
"source": "",
"offset": 0,
"callstack": new list<hash<CallStackInfo>>(),
"lang": "Qore",
"err": 1,
)),
),
Expand All @@ -67,7 +67,10 @@ class ProgramVarsTest inherits QUnit::Test {
"value": NOTHING,
),
);
assertEq(vh, p.callFunction("test3"));
auto v = p.callFunction("test3");
# remove the call stack
v.ex.value -= "callstack";
assertEq(vh, v);
}
}
}
32 changes: 32 additions & 0 deletions examples/test/qore/functions/get_ex_pos.qtest
@@ -0,0 +1,32 @@
#!/usr/bin/env qore
# -*- mode: qore; indent-tabs-mode: nil -*-

%new-style
%enable-all-warnings
%require-types
%strict-args

%requires ../../../../qlib/QUnit.qm

%exec-class GetExPosTest

public class GetExPosTest inherits QUnit::Test {
constructor() : Test("GetExPosTest", "1.0") {
addTestCase("get_ex_pos() test", \getExPosTest());

# Return for compatibility with test harness that checks return value.
set_return_value(main());
}

getExPosTest() {
try {
if (True) {
throw "ERR", "desc";
}
assertTrue(False);
} catch (hash<ExceptionInfo> ex) {
string str = get_ex_pos(ex);
assertRegex("get_ex_pos.qtest:24 \\(Qore\\)$", str);
}
}
}
95 changes: 15 additions & 80 deletions examples/test/qore/misc/exception.qtest
Expand Up @@ -12,62 +12,42 @@

class ExceptionTest inherits QUnit::Test {
private {
string err;
string err2;
string err3;
string desc;
string arg;
string type;
hash<ExceptionInfo> ex;
}

constructor() : QUnit::Test("Exception test", "1.0") {
addTestCase("Test simple try/catch block", \testSimpleTryCatch());
addTestCase("Test rethrow", \testRethrow());
addTestCase("misc tests", \miscTests());
#addTestCase("Complex try/catch hierarchy", \testComplexHierarchy());
set_return_value(main());
}

setUp() {
err = '';
err2 = '';
err3 = '';
desc = '';
arg = '';
type = '';
}

testSimpleTryCatch() {
try {
throw "testing", "123", "test";
} catch (hash<ExceptionInfo> ex1) {
ex = ex1;
}
catch (ex) {
err = ex.err;
desc = ex.desc;
arg = ex.arg;
}
assertEq("testing", err);
assertEq("123", desc);
assertEq("test", arg);
assertEq("testing", ex.err);
assertEq("123", ex.desc);
assertEq("test", ex.arg);
assertEq("Qore", ex.lang);
}

testRethrow() {
try {
try {
throw "TEST-ERROR", "this is a test";
}
catch () {
} catch () {
rethrow;
}
} catch (hash<ExceptionInfo> ex1) {
ex = ex1;
}
catch (ex) {
err = ex.err;
desc = ex.desc;
type = ex.type;
}
assertEq("TEST-ERROR", err);
assertEq("this is a test", desc);
assertEq("User", type);
assertEq("TEST-ERROR", ex.err);
assertEq("this is a test", ex.desc);
assertEq("User", ex.type);
assertEq("Qore", ex.lang);
}

miscTests() {
Expand All @@ -77,53 +57,8 @@ class ExceptionTest inherits QUnit::Test {
int a = 1;
try {
throw a;
}
catch (hash<ExceptionInfo> ex) {
} catch (hash<ExceptionInfo> ex) {
assertEq(1, ex.err);
}
}

/*testComplexHierarchy() {
try {
try {
try {
printf("%s\n", snope.refresh());
}
catch (ex) {
err = ex.err;

try {
try {
context gee (gee) where (%foo == "gee")
printf("%s\n", sdfdas);
}
catch (ex1) {
desc = shift argv;
printf("QORE %s Exception in line %d of file %s: %s: %s\n",
ex1.type, ex1.line, ex1.file, ex1.err, ex1.desc);
throw snope.blah();
}
throw snope.sdfds();
}
catch (ex2) {
err2 = ex2.err;
throw "TEST";
}
}
}
catch (ex) {
err3 = ex.err;
}
}
catch (ex) {
printf("QORE %s Exception in line %d of file %s: %s: %s\n",
ex.type, ex.line, ex.file, ex.err, ex.desc);
context (gee) where (%whiz == "wdsf")
printf("%s\n", %dsfdf);
}

assertEq("PSEUDO-METHOD-DOES-NOT-EXIST", err);
assertEq("PSEUDO-METHOD-DOES-NOT-EXIST", err2);
assertEq("TEST", err3);
}*/
}
2 changes: 1 addition & 1 deletion examples/test/qore/misc/has_effect.qtest
Expand Up @@ -33,7 +33,7 @@ public class HasEffectTest inherits QUnit::Test {
assertEq(NOTHING, parse_result);
if (testBackground) {
Program p3(PO_NEW_STYLE|PO_ALLOW_STATEMENT_NO_EFFECT);
*hash parse_result = p3.parse("background " + statements, "");
parse_result = p3.parse("background " + statements, "");
assertEq(NOTHING, parse_result);
}
}
Expand Down
8 changes: 5 additions & 3 deletions examples/test/qore/stack/get-call-stack.qtest
Expand Up @@ -16,14 +16,16 @@ class GetCallThreadTest inherits QUnit::Test {
set_return_value(main());
}

any f2(bool all) {
auto f2(bool all) {
return all ? get_all_thread_call_stacks() : get_thread_call_stack();
}
any f1(bool all) {

auto f1(bool all) {
return f2(all);
}

testGetCallThread() {
hash h = f1(True);
hash<auto> h = f1(True);
testAssertionValue("get_all_thread_call_stacks-0", h{gettid()}[0].function, "get_all_thread_call_stacks");
testAssertionValue("get_all_thread_call_stacks-1", h{gettid()}[1].function, "GetCallThreadTest::f2");
testAssertionValue("get_all_thread_call_stacks-2", h{gettid()}[2].function, "GetCallThreadTest::f1");
Expand Down