Best Known Configurations for Debugging
Using the LLVM Backend
When debugging Chapel using the default LLVM backend, make sure to use the
-g
flag to generate debug symbols in the executable. This will allow you to
use a debugger like gdb
or lldb
to step through the code and inspect
variables.
There are a few flags that may be useful for debugging with the LLVM backend. For example, the following is the current best configuration which results in generated code with the best possible debug information:
chpl -g --preserve-inlined-line-numbers \
--no-return-by-ref --no-inline \
--no-copy-propagation --no-scalar-replacement <source_file>
If you intend to use gdb
to debug your Chapel program, you may also want to
use the --ccflags -gdwarf-4
, as gdb
has been found to have issues with
DWARF 5 debug information generated by the LLVM backend.
chpl -g --ccflags -gdwarf-4 --preserve-inlined-line-numbers \
--no-return-by-ref --no-inline \
--no-copy-propagation --no-scalar-replacement <source_file>
The following table summarizes the flags that can be used to improve the debuggability of the generated executable:
Flag
Description
-g
Generate debug symbols in the executable
--ccflags -gdwarf-4
Use DWARF 4 debug information (useful for
gdb
)
--preserve-inlined-line-numbers
When code gets inlined (e.g. replacing a function call with the function body) maintain the filename and line number information of the original function.
--no-return-by-ref
Don’t use an extra reference argument when compiling a Chapel function that returns a record.
--no-inline
Avoid inlining in many cases.
--no-copy-propagation
Disables a Chapel optimization pass that can make debugging harder.
--no-scalar-replacement
Disables a Chapel optimization pass that can make debugging harder.
Using the C Backend
It may be useful to debug Chapel programs using the C backend. The current best
practice for debugging Chapel source code with the C backend is to use a series
of flags to improve the debuggability of the generated executable. While
debugging with just -g
is possible, these flags (explained in step 2 below)
result in generated code with debug information that most closely matches the
Chapel source code. This can be done in two steps.
Build the compiler with
CHPL_TARGET_COMPILER
set tognu
(orclang
if on Mac):CHPL_TARGET_COMPILER=gnu make # On MacOS # CHPL_TARGET_COMPILER=clang make
Build the executable from Chapel source code:
chpl -g --target-compiler=gnu --preserve-inlined-line-numbers \ --no-munge-user-idents --no-return-by-ref --no-inline \ --no-copy-propagation --no-scalar-replacement <source_file> # On MacOS # chpl -g --target-compiler=clang --preserve-inlined-line-numbers \ # --no-munge-user-idents --no-return-by-ref --no-inline \ # --no-copy-propagation --no-scalar-replacement <source_file>
For more details on these settings, read the rest of this section.
Building the Compiler
For best results while debugging, we recommend building the compiler with
CHPL_TARGET_COMPILER
set to gnu
(or clang
if on Mac). See
Setting up Your Environment for Chapel for more information on building the compiler.
With two invocations of the build command, both backends can be built. First
execute make
(which uses the LLVM backend by default) and then execute
CHPL_TARGET_COMPILER=gnu make
. This will keep the default as LLVM and allow
switching to the C backend as needed for debugging. This can be done for a
particular invocation of the compiler with chpl --target-compiler=gnu ...
.
Building the Application
The following flags can be useful for making the generated C more amenable to debugging. Any of them can be omitted as desired.
Flag
Description
-g
Generate debug symbols in the executable
--target-compiler=gnu
Target the C backend with GCC
--target-compiler=clang
Target the C backend with Clang
--savec <dir>
Write out the generated C to a given directory
--preserve-inlined-line-numbers
When code gets inlined (e.g. replacing a function call with the function body) maintain the filename and line number information of the original function.
--no-munge-user-idents
Don’t munge user identifiers (e.g. variable or function names). Munging typically prevents conflicts with identifiers in external code but makes debugging harder.
--no-return-by-ref
Don’t use an extra reference argument when compiling a Chapel function that returns a record.
--no-inline
Avoid inlining in many cases.
--no-copy-propagation
Disables a Chapel optimization pass that can make debugging harder.
--no-scalar-replacement
Disables a Chapel optimization pass that can make debugging harder.
Notes on Munging
The utility of using a debugger with Chapel depends greatly on your familiarity
with the Chapel generated code. However, if your program is crashing or running
into a runtime error, you can often determine where that is taking place by
looking at a stack trace within gdb
.
When debugging Chapel, it is useful to know that in generating its code,
the Chapel compiler renames user identifiers. By default, the Chapel
compiler munges all user identifiers, such that a variable named x
would be code-generated as x_chpl
. This munging can be controlled
using the --[no-]munge-user-idents
flag (see the chpl
man page
for more information). In some cases, additional munging may be
required or applied that cannot be turned off.
The net effect of this is that Chapel variables can often be inspected
using p
name_chpl
(or p
name_chpl<TAB>
in cases
where the compiler has further renamed the variable). If the
--no-munge-user-idents
flag is used, p
name or
p
name<TAB>
should work in most cases.
See Why are my identifiers renamed in the generated code? for more information on munging.