From f6969631a64d6137ab9cfaae92ebf983c6fd067c Mon Sep 17 00:00:00 2001 From: Mark Olesen Date: Tue, 21 Mar 2023 20:27:10 +0100 Subject: [PATCH] ENH: support optional upper limit for printStack - when only a partial stacktrace is desirable. ENH: add stack trace decorators - the 0-th frame is always printStack(), so skip that and emit some headers/footers instead. Eg, [stack trace] ============= #1 Foam::SymmTensor Foam::inv(...) #2 Foam::inv(Foam::UList> const&) ... ... ============= --- .../MSwindows/printStack/dummyPrintStack.C | 7 ++--- .../POSIX/printStack/dummyPrintStack.C | 7 ++--- src/OSspecific/POSIX/printStack/printStack.C | 27 ++++++++++++++----- src/OpenFOAM/db/error/error.H | 12 ++++----- 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/src/OSspecific/MSwindows/printStack/dummyPrintStack.C b/src/OSspecific/MSwindows/printStack/dummyPrintStack.C index 04b635dbb1..61bf8f63a6 100644 --- a/src/OSspecific/MSwindows/printStack/dummyPrintStack.C +++ b/src/OSspecific/MSwindows/printStack/dummyPrintStack.C @@ -5,7 +5,8 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2011-2017 OpenFOAM Foundation + Copyright (C) 2011 OpenFOAM Foundation + Copyright (C) 2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -29,11 +30,11 @@ License // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -void Foam::error::safePrintStack(std::ostream& os) +void Foam::error::safePrintStack(std::ostream& os, int size) {} -void Foam::error::printStack(Ostream& os) +void Foam::error::printStack(Ostream& os, int size) {} diff --git a/src/OSspecific/POSIX/printStack/dummyPrintStack.C b/src/OSspecific/POSIX/printStack/dummyPrintStack.C index 04b635dbb1..61bf8f63a6 100644 --- a/src/OSspecific/POSIX/printStack/dummyPrintStack.C +++ b/src/OSspecific/POSIX/printStack/dummyPrintStack.C @@ -5,7 +5,8 @@ \\ / A nd | www.openfoam.com \\/ M anipulation | ------------------------------------------------------------------------------- - Copyright (C) 2011-2017 OpenFOAM Foundation + Copyright (C) 2011 OpenFOAM Foundation + Copyright (C) 2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -29,11 +30,11 @@ License // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -void Foam::error::safePrintStack(std::ostream& os) +void Foam::error::safePrintStack(std::ostream& os, int size) {} -void Foam::error::printStack(Ostream& os) +void Foam::error::printStack(Ostream& os, int size) {} diff --git a/src/OSspecific/POSIX/printStack/printStack.C b/src/OSspecific/POSIX/printStack/printStack.C index 358ee8e8c0..a492937696 100644 --- a/src/OSspecific/POSIX/printStack/printStack.C +++ b/src/OSspecific/POSIX/printStack/printStack.C @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2016 OpenFOAM Foundation - Copyright (C) 2019-2022 OpenCFD Ltd. + Copyright (C) 2019-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -201,15 +201,20 @@ inline Foam::fileName whichPath(const char* fn) // * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * // -void Foam::error::safePrintStack(std::ostream& os) +void Foam::error::safePrintStack(std::ostream& os, int size) { // Get raw stack symbols void *callstack[100]; - const int size = backtrace(callstack, 100); + size = backtrace(callstack, (size > 0 && size < 100) ? size + 1 : 100); + char **strings = backtrace_symbols(callstack, size); size_t rdelim; - for (int i = 0; i < size; ++i) + // Frame 0 is 'printStack()' - report something more meaningful + os << "[stack trace]" << std::endl + << "=============" << std::endl; + + for (int i = 1; i < size; ++i) { std::string str(strings[i]); @@ -269,20 +274,26 @@ void Foam::error::safePrintStack(std::ostream& os) os << std::endl; } + os << "=============" << std::endl; + free(strings); } -void Foam::error::printStack(Ostream& os) +void Foam::error::printStack(Ostream& os, int size) { // Get raw stack symbols void *callstack[100]; - const int size = backtrace(callstack, 100); + size = backtrace(callstack, (size > 0 && size < 100) ? size + 1 : 100); Dl_info info; fileName fname; - for (int i = 0; i < size; ++i) + // Frame 0 is 'printStack()' - report something more meaningful + os << "[stack trace]" << nl + << "=============" << nl; + + for (int i = 1; i < size; ++i) { int st = dladdr(callstack[i], &info); @@ -309,6 +320,8 @@ void Foam::error::printStack(Ostream& os) printSourceFileAndLine(os, fname, info, callstack[i]); os << nl; } + + os << "=============" << nl; } diff --git a/src/OpenFOAM/db/error/error.H b/src/OpenFOAM/db/error/error.H index 22fe3ad136..36b5a200bc 100644 --- a/src/OpenFOAM/db/error/error.H +++ b/src/OpenFOAM/db/error/error.H @@ -6,7 +6,7 @@ \\/ M anipulation | ------------------------------------------------------------------------------- Copyright (C) 2011-2015 OpenFOAM Foundation - Copyright (C) 2015-2021 OpenCFD Ltd. + Copyright (C) 2015-2023 OpenCFD Ltd. ------------------------------------------------------------------------------- License This file is part of OpenFOAM. @@ -231,12 +231,12 @@ public: operator dictionary() const; - //- Helper function to print a stack, - //- used when OpenFOAM IO not yet initialised. - static void safePrintStack(std::ostream& os); + //- Helper function to print a stack, with optional upper limit. + //- Used when OpenFOAM IO not yet initialised. + static void safePrintStack(std::ostream& os, int size = -1); - //- Helper function to print a stack - static void printStack(Ostream& os); + //- Helper function to print a stack, with optional upper limit. + static void printStack(Ostream& os, int size = -1); //- True if FOAM_ABORT is on. static bool useAbort();