Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
d9e789c
Switch to `cpptrace` for stack traces in exceptions
ZedThree Dec 5, 2025
199ba5a
Add some control over `BoutException` backtraces
ZedThree Dec 5, 2025
dc865d3
Try to ensure `build_defines` is included where it's used
ZedThree Dec 5, 2025
e0710f8
Try to make backtrace unit test more portable
ZedThree Dec 16, 2025
9dd86c5
cmake: Fix some issues with building with cpptrace
ZedThree Jan 5, 2026
00995ea
Prettify symbols in cpptrace output
ZedThree Jan 5, 2026
3fc530d
Filter out pre-main functions from stacktrace
ZedThree Jan 5, 2026
5f77485
Include filtered placeholders
ZedThree Jan 5, 2026
cbc4cf2
Remove `AUTO_TRACE` macro
ZedThree Jan 5, 2026
505d5ad
Remove uses of `TRACE` which are just the function name
ZedThree Jan 5, 2026
63e78ae
Fix unnecessary includes of `msg_stack.hxx`
ZedThree Jan 5, 2026
c42afa3
Don't duplicate exception message when thrown from `BoutInitialise`
ZedThree Jan 5, 2026
6d89b6f
Don't print `MsgStack` dump if it's empty
ZedThree Jan 5, 2026
8896f6e
Apply clang-format changes
ZedThree Jan 5, 2026
e497fcd
docs: Use build directory for building library
ZedThree Jan 5, 2026
6ccdca8
Partial revert of d0cd5f0aee
ZedThree Jan 5, 2026
d8b360f
Remove some more unused headers
ZedThree Jan 6, 2026
5306125
tests: Add functions to anon namespace
ZedThree Jan 6, 2026
68fab1b
Don't use `char[]` for constant
ZedThree Jan 6, 2026
563ab24
Fix use of reserved identifier
ZedThree Jan 6, 2026
1a9210c
docs: Update example backtrace
ZedThree Jan 6, 2026
4ac87c1
docs: Expand on using `cpptrace` and the backtrace
ZedThree Jan 8, 2026
73e5857
Apply clang-format changes
ZedThree Jan 8, 2026
8edb351
tests: Fix exception test inlining functions
ZedThree Jan 8, 2026
6b03b6c
Apply black changes
ZedThree Jan 8, 2026
9855b5f
Add `cpptrace` as git submodule
ZedThree Jan 9, 2026
7fa1c5f
boutpp: Add `cpptrace` to sdist
ZedThree Jan 9, 2026
68904f9
docs: Init all submodules
ZedThree Jan 9, 2026
4a09719
cmake: Update cpptrace include dir for install
ZedThree Jan 9, 2026
52299ea
docs: Fix building `boutpp` docs on readthedocs
ZedThree Jan 19, 2026
60546f6
docs: Exclude CMake-built dependencies from docs
ZedThree Jan 19, 2026
f9cb4d8
docs: Use builtin path to Python to set location for CMake
ZedThree Jan 19, 2026
3252e41
docs: Remove outdated comment
ZedThree Jan 19, 2026
876fe2c
Apply black changes
ZedThree Jan 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .clang-tidy
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ CheckOptions:
value: 'MPI_Comm'

- key: misc-include-cleaner.IgnoreHeaders
value: 'adios2/.*;bits/.*'
value: 'adios2/.*;bits/.*;cpptrace/.*'
---

Disabled checks and reasons:
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@
[submodule "externalpackages/boutdata"]
path = externalpackages/boutdata
url = https://github.com/boutproject/boutdata.git
[submodule "externalpackages/cpptrace"]
path = externalpackages/cpptrace
url = https://github.com/ZedThree/cpptrace.git
16 changes: 3 additions & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -574,18 +574,6 @@ option(BOUT_ENABLE_SIGFPE "Signalling floating point exceptions" OFF)
message(STATUS "Signalling floating point exceptions: BOUT_USE_SIGFPE=${BOUT_ENABLE_SIGFPE}")
set(BOUT_USE_SIGFPE ${BOUT_ENABLE_SIGFPE})

option(BOUT_ENABLE_BACKTRACE "Enable backtrace" ON)
if (BOUT_ENABLE_BACKTRACE)
find_program(ADDR2LINE_FOUND addr2line)
if (NOT ADDR2LINE_FOUND)
message(FATAL_ERROR "addr2line not found. Disable backtrace by setting BOUT_ENABLE_BACKTRACE=Off")
endif()
target_link_libraries(bout++ PUBLIC ${CMAKE_DL_LIBS})
set(CONFIG_LDFLAGS "${CONFIG_LDFLAGS} -l${CMAKE_DL_LIBS}")
endif()
message(STATUS "Enable backtrace: BOUT_USE_BACKTRACE=${BOUT_ENABLE_BACKTRACE}")
set(BOUT_USE_BACKTRACE ${BOUT_ENABLE_BACKTRACE})

option(BOUT_ENABLE_METRIC_3D "Enable 3D metric support" OFF)
if(BOUT_ENABLE_METRIC_3D)
set(BOUT_METRIC_TYPE "3D")
Expand Down Expand Up @@ -830,6 +818,9 @@ endif()
if (NOT BOUT_USE_SYSTEM_FMT)
set(FMT_INCLUDE_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}")
endif()
if (NOT BOUT_USE_SYSTEM_CPPTRACE)
set(CPPTRACE_INCLUDE_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}")
endif()
set(BOUT_INCLUDE_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_INCLUDEDIR}")
# We don't need the build include path any more
string(REPLACE "-I${CMAKE_CURRENT_BINARY_DIR}/include" "" CONFIG_CFLAGS "${CONFIG_CFLAGS}")
Expand Down Expand Up @@ -958,7 +949,6 @@ message("
Output coloring : ${BOUT_USE_COLOR}
Field name tracking : ${BOUT_USE_TRACK}
Floating point exceptions: ${BOUT_USE_SIGFPE}
Backtrace enabled : ${BOUT_USE_BACKTRACE}
RAJA enabled : ${BOUT_HAS_RAJA}
Umpire enabled : ${BOUT_HAS_UMPIRE}
Caliper enabled : ${BOUT_HAS_CALIPER}
Expand Down
12 changes: 4 additions & 8 deletions bin/bout-add-mod-path
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,7 @@ def create_mod(modulepath, name, top, build):
else:
prereq = ""
with open(filename, "w") as f:
f.write(
f"""#%Module 1.0
f.write(f"""#%Module 1.0
#
# BOUT++ module for use with 'environment-modules' package
# Created by bout-add-mod-path v0.9
Expand All @@ -119,17 +118,14 @@ setenv BOUT_TOP {top}
prepend-path PATH {top}/bin
prepend-path PYTHONPATH {top}/tools/pylib
prepend-path IDL_PATH +{top}/tools/idllib:'<IDL_DEFAULT>'
"""
)
""")
if build != top:
f.write(
f"""#%Module 1.0
f.write(f"""#%Module 1.0
setenv BOUT_BUILD {build}
prepend-path PATH {build}/bin
prepend-path LD_LIBRARY_PATH {build}/lib
prepend-path PYTHONPATH {build}/tools/pylib
"""
)
""")
print(f"created `{filename}`")


Expand Down
31 changes: 10 additions & 21 deletions bin/bout-pylib-cmd-to-bin
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,7 @@ def createwrapper(mod, func_name, func, name):
out += end
f.write(out)

fprint(
"""#!/usr/bin/env python3
fprint("""#!/usr/bin/env python3
# PYTHON_ARGCOMPLETE_OK

import argparse
Expand All @@ -136,8 +135,7 @@ try:
except ImportError:
argcomplete=None

"""
)
""")
doc = True
para = False
ret = False
Expand Down Expand Up @@ -183,19 +181,16 @@ except ImportError:
arg_help[curarg].append(esc(blas))
# Print functions that are needed
if "str_to_slice" in arg_type.values():
fprint(
"""
fprint("""
def str_to_slice(sstr):
args=[]
for s in sstr.split(','):
args.append(int(s))
print(args)
return slice(*args)
"""
)
""")
if "str_to_bool" in arg_type.values():
fprint(
"""
fprint("""
def str_to_bool(sstr):
low=sstr.lower()
# no or false
Expand All @@ -206,8 +201,7 @@ def str_to_bool(sstr):
return True
else:
raise ArgumentTypeError("Cannot parse %s to bool type"%sstr)
"""
)
""")
# Create the parser
fprint("parser = argparse.ArgumentParser(%s)" % (esc(docs)))
spec = inspect.signature(func)
Expand Down Expand Up @@ -247,24 +241,19 @@ def str_to_bool(sstr):
pre = "\n "
fprint(")")

fprint(
"""
fprint("""
if argcomplete:
argcomplete.autocomplete(parser)

# late import for faster auto-complete"""
)
# late import for faster auto-complete""")
fprint("from %s import %s" % (mod, func_name))
fprint(
"""
fprint("""
args = parser.parse_args()

# Call the function %s, using command line arguments
%s(**args.__dict__)

"""
% (func_name, func_name)
)
""" % (func_name, func_name))
# alternative, but I think 0o755 is easier to read
# import stat
# os.chmod(filename,stat.S_IRWXU|stat.S_IRGRP|stat.S_IXGRP|stat.S_IROTH|stat.S_IXOTH)
Expand Down
21 changes: 5 additions & 16 deletions bin/bout-v5-factory-upgrader.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import difflib
import re


# Dictionary of factory methods that may need updating
factories = {
"Interpolation": {
Expand Down Expand Up @@ -62,9 +61,7 @@ def find_factory_calls(factory, source):
\s*=\s*
{factory_name}::
.*{create_method}.*
""".format(
**factory
),
""".format(**factory),
source,
re.VERBOSE,
)
Expand All @@ -75,9 +72,7 @@ def find_type_pointers(factory, source):
r"""
\b{type_name}\s*\*\s* # Type name and pointer
([\w_]+)\s*; # Variable name
""".format(
**factory
),
""".format(**factory),
source,
re.VERBOSE,
)
Expand Down Expand Up @@ -107,9 +102,7 @@ def fix_declarations(factory, variables, source):
(.*?)(class\s*)? # optional "class" keyword
\b({type_name})\s*\*\s* # Type-pointer
({variable_name})\s*; # Variable
""".format(
type_name=factory["type_name"], variable_name=variable
),
""".format(type_name=factory["type_name"], variable_name=variable),
r"\1std::unique_ptr<\3> \4{nullptr};",
source,
flags=re.VERBOSE,
Expand All @@ -123,9 +116,7 @@ def fix_declarations(factory, variables, source):
({variable_name})\s* # Variable
=\s* # Assignment from factory
({factory_name}::.*{create_method}.*);
""".format(
variable_name=variable, **factory
),
""".format(variable_name=variable, **factory),
r"\1auto \4 = \5;",
source,
flags=re.VERBOSE,
Expand All @@ -139,9 +130,7 @@ def fix_declarations(factory, variables, source):
({variable_name})\s* # Variable
=\s* # Assignment
(0|nullptr|NULL);
""".format(
variable_name=variable, **factory
),
""".format(variable_name=variable, **factory),
r"\1std::unique_ptr<\2> \3{nullptr};",
source,
flags=re.VERBOSE,
Expand Down
1 change: 0 additions & 1 deletion bin/bout-v5-format-upgrader.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import difflib
import re


format_replacements = {
"c": "c",
"d": "d",
Expand Down
7 changes: 2 additions & 5 deletions bin/bout-v5-header-upgrader.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
from typing import List
from subprocess import run


header_shim_sentinel = "// BOUT++ header shim"

header_warning = f"""\
Expand Down Expand Up @@ -122,8 +121,7 @@ def create_patch(filename, original, modified):
if __name__ == "__main__":
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description=textwrap.dedent(
"""\
description=textwrap.dedent("""\
Fix deprecated header locations for BOUT++ v4 -> v5

All BOUT++ headers are now under ``include/bout`` and
Expand All @@ -142,8 +140,7 @@ def create_patch(filename, original, modified):
If you have staged changes, this tool will not work, so to
avoid committing undesired or unrelated changes.

"""
),
"""),
)

parser.add_argument(
Expand Down
6 changes: 2 additions & 4 deletions bin/bout-v5-input-file-upgrader.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,7 @@ def possibly_apply_patch(patch, options_file, quiet=False, force=False):
if __name__ == "__main__":
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description=textwrap.dedent(
"""\
description=textwrap.dedent("""\
Fix input files for BOUT++ v5+

Please note that this will only fix input options in sections with
Expand Down Expand Up @@ -300,8 +299,7 @@ def possibly_apply_patch(patch, options_file, quiet=False, force=False):

Files that change in this way will have the "canonicalisation" patch
presented first. If you choose not to apply this patch, the "upgrade
fixer" patch will still include it."""
),
fixer" patch will still include it."""),
)

parser.add_argument("files", action="store", nargs="+", help="Input files")
Expand Down
6 changes: 2 additions & 4 deletions bin/bout-v5-macro-upgrader.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,8 +342,7 @@ def create_patch(filename, original, modified):
if __name__ == "__main__":
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description=textwrap.dedent(
"""\
description=textwrap.dedent("""\
Fix macro defines for BOUT++ v4 -> v5

Please note that this is only slightly better than dumb text replacement. It
Expand All @@ -359,8 +358,7 @@ def create_patch(filename, original, modified):
still replace them in strings or comments.

Please check the diff output carefully!
"""
),
"""),
)

parser.add_argument("files", action="store", nargs="+", help="Input files")
Expand Down
13 changes: 4 additions & 9 deletions bin/bout-v5-physics-model-upgrader.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import textwrap
import warnings


PHYSICS_MODEL_INCLUDE = '#include "bout/physicsmodel.hxx"'

PHYSICS_MODEL_SKELETON = """
Expand Down Expand Up @@ -213,13 +212,11 @@ def fix_bout_constrain(source, error_on_warning):
"\n ".join(["{}:{}".format(i, source_lines[i]) for i in line_range])
)

message = textwrap.dedent(
"""\
message = textwrap.dedent("""\
Some uses of `bout_constrain` remain, but we could not automatically
convert them to use `Solver::constraint`. Please fix them before
continuing:
"""
)
""")
message += " " + "\n ".join(lines_context)

if error_on_warning:
Expand Down Expand Up @@ -389,8 +386,7 @@ def create_patch(filename, original, modified):
if __name__ == "__main__":
parser = argparse.ArgumentParser(
formatter_class=argparse.RawDescriptionHelpFormatter,
description=textwrap.dedent(
"""\
description=textwrap.dedent("""\
Upgrade legacy physics models to use the PhysicsModel class

This will do the bare minimum required to compile, and
Expand All @@ -403,8 +399,7 @@ def create_patch(filename, original, modified):
By default, this will use the file name stripped of file
extensions as the name of the new class. Use '--name=<new
name>' to give a different name.
"""
),
"""),
)

parser.add_argument("files", action="store", nargs="+", help="Files to fix")
Expand Down
12 changes: 3 additions & 9 deletions bin/bout-v5-xzinterpolation-upgrader.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@ def fix_header_includes(old_header, new_header, source):
(<|")
({header}) # Header name
(>|")
""".format(
header=old_header
),
""".format(header=old_header),
r"\1\2{header}\4".format(header=new_header),
source,
flags=re.VERBOSE,
Expand All @@ -67,9 +65,7 @@ def fix_interpolations(old_interpolation, new_interpolation, source):
return re.sub(
r"""
\b{}\b
""".format(
old_interpolation
),
""".format(old_interpolation),
r"{}".format(new_interpolation),
source,
flags=re.VERBOSE,
Expand Down Expand Up @@ -120,9 +116,7 @@ def fix_factories(old_factory, new_factory, source):
return re.sub(
r"""
\b{}\b
""".format(
old_factory
),
""".format(old_factory),
r"{}".format(new_factory),
source,
flags=re.VERBOSE,
Expand Down
Loading