CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
148 lines
7.1 KiB
Markdown
148 lines
7.1 KiB
Markdown
# Contributing
|
|
|
|
## Getting Started
|
|
|
|
Please refer to the [LLVM Getting Started Guide](https://llvm.org/docs/GettingStarted.html) for general information on how to
|
|
get started on the LLVM project. A detailed explanation on how to build and
|
|
test LLDB can be found in the {doc}`build instructions <build>` and
|
|
{doc}`test instructions <test>` respectively.
|
|
|
|
## Contributing to LLDB
|
|
|
|
Please refer to the [LLVM Developer Policy](https://llvm.org/docs/DeveloperPolicy.html) for information about
|
|
authoring and uploading a patch. LLDB differs from the LLVM Developer
|
|
Policy in the following respects.
|
|
|
|
For anything not explicitly listed here, assume that LLDB follows the LLVM
|
|
policy.
|
|
|
|
### Coding Style
|
|
|
|
LLDB's code style differs from [LLVM's coding style](https://llvm.org/docs/CodingStandards.html)
|
|
in a few ways. The 2 main ones are:
|
|
|
|
- [Variable and function naming](https://llvm.org/docs/CodingStandards.html#name-types-functions-variables-and-enumerators-properly):
|
|
|
|
- Variables are `snake_case`.
|
|
- Functions and methods are `UpperCamelCase`.
|
|
- Static, global and member variables have `s_`, `g_` and `m_`
|
|
prefixes respectively.
|
|
|
|
- [Use of asserts](https://llvm.org/docs/CodingStandards.html#assert-liberally):
|
|
See the {ref}`section below<error-handling>`.
|
|
|
|
For any other contradictions, consider the
|
|
[golden rule](https://llvm.org/docs/CodingStandards.html#introduction)
|
|
before choosing to update the style of existing code.
|
|
|
|
All new code in LLDB should be formatted with clang-format. Existing code may
|
|
not conform and should be updated prior to being modified. Bulk reformatting
|
|
is discouraged.
|
|
|
|
### Test Infrastructure
|
|
|
|
Like LLVM it is important to submit tests with your patches, but note that a
|
|
subset of LLDB tests (the API tests) use a different system. Refer to the
|
|
{doc}`test documentation <test>` for more details and the
|
|
[lldb/test](https://github.com/llvm/llvm-project/tree/main/lldb/test) folder
|
|
for examples.
|
|
|
|
## LLDB plugins and their dependencies
|
|
|
|
LLDB has a concept of *plugins*, which are used to provide abstraction
|
|
boundaries over functionality that is specific to a certain architecture,
|
|
operating system, programming language, etc. A plugin implements an abstract
|
|
base class (rarely, a set of related base classes), which is a part of LLDB
|
|
core. This setup allows the LLDB core to remain generic while making it possible
|
|
to support for new architectures, languages, and so on. For this to work, all
|
|
code needs to obey certain rules.
|
|
|
|
The principal rule is that LLDB core (defined as: everything under lldb/source
|
|
*minus* lldb/source/Plugins) must not depend on any specific plugin. The only
|
|
way it can interact with them is through the abstract interface. Explicit
|
|
dependencies such as casting the base class to the plugin type are not permitted
|
|
and neither are more subtle dependencies like checking the name plugin or or
|
|
other situations where some code in LLDB core is tightly coupled to the
|
|
implementation details of a specific plugin.
|
|
|
|
The rule for interaction between different plugins is more nuanced. We recognize
|
|
that some cross-plugin dependencies are unavoidable or even desirable. For
|
|
example, a plugin may want to extend a plugin of the same kind to
|
|
add/override/refine some functionality (e.g., Android is a "kind of" Linux, but
|
|
it handles some things differently). Alternatively, a plugin of one kind may
|
|
want to build on the functionality offered by a specific plugin of another kind
|
|
(ELFCore Process plugin uses ELF ObjectFile plugin to create a process out of an
|
|
ELF core file).
|
|
|
|
In cases such as these, direct dependencies are acceptable. However, to keep the
|
|
dependency graph manageable, we still have some rules to govern these
|
|
relationships:
|
|
|
|
- All dependencies between plugins of the same kind must flow in the same
|
|
direction (if plugin `A1` depends on plugin `B1`, then `B2` must not depend on
|
|
`A2`)
|
|
- Dependency graph of plugin kinds must not contain loops (dependencies like
|
|
`A1->B1`, `B2->C2` and `C3->A3` are forbidden because they induce a cycle in
|
|
the plugin kind graph even though the plugins themselves are acyclical)
|
|
|
|
The first of these rules is checked via CMake scripts (using the
|
|
`LLDB_ACCEPTABLE_PLUGIN_DEPENDENCIES` property). Dependencies in this category
|
|
are expected and permitted (subject to other constraints such as that dependency
|
|
making sense for the particular pair of plugins). Unfortunately, due to historic
|
|
reasons, not all plugin dependencies follow this rule, which is why we have
|
|
another category called `LLDB_TOLERATED_PLUGIN_DEPENDENCIES`. New dependencies
|
|
are forbidden (even though they are accepted by CMake) and existing ones should
|
|
be removed wherever possible.
|
|
|
|
(error-handling)=
|
|
|
|
## Error handling and use of assertions in LLDB
|
|
|
|
Contrary to Clang, which is typically a short-lived process, LLDB
|
|
debuggers stay up and running for a long time, often serving multiple
|
|
debug sessions initiated by an IDE. For this reason LLDB code needs to
|
|
be extra thoughtful about how to handle errors. Below are a couple
|
|
rules of thumb:
|
|
|
|
- Invalid input. To deal with invalid input, such as malformed DWARF,
|
|
missing object files, or otherwise inconsistent debug info,
|
|
error handling types such as [llvm::Expected\<T>](https://llvm.org/doxygen/classllvm_1_1Expected.html) or
|
|
`std::optional<T>` should be used. Functions that may fail
|
|
should return their result using these wrapper types instead of
|
|
using a bool to indicate success. Returning a default value when an
|
|
error occurred is also discouraged.
|
|
- Assertions. Assertions (from `assert.h`) should be used liberally
|
|
to assert internal consistency. Assertions shall **never** be
|
|
used to detect invalid user input, such as malformed DWARF. An
|
|
assertion should be placed to assert invariants that the developer
|
|
is convinced will always hold, regardless what an end-user does with
|
|
LLDB. Because assertions are not present in release builds, the
|
|
checks in an assertion may be more expensive than otherwise
|
|
permissible. In combination with the LLDB test suite, assertions are
|
|
what allows us to refactor and evolve the LLDB code base.
|
|
- Logging. LLDB provides a very rich logging API. When recoverable
|
|
errors cannot reasonably be surfaced to the end user, the error may
|
|
be written to a topical log channel.
|
|
- Soft assertions. LLDB provides `lldbassert()` as a soft
|
|
alternative to cover the middle ground of situations that indicate a
|
|
recoverable bug in LLDB. When asserts are enabled `lldbassert()`
|
|
behaves like `assert()`. When asserts are disabled, it will print a
|
|
warning and encourage the user to file a bug report, similar to
|
|
LLVM's crash handler, and then return execution. Use these sparingly
|
|
and only if error handling is not otherwise feasible.
|
|
|
|
:::{note}
|
|
New code should not be using `lldbassert()` and existing uses should
|
|
be replaced by other means of error handling.
|
|
:::
|
|
|
|
- Fatal errors. Aborting LLDB's process using
|
|
`llvm::report_fatal_error()` or `abort()` should be avoided at all
|
|
costs. It's acceptable to use `llvm_unreachable()` for actually
|
|
unreachable code such as the default in an otherwise exhaustive
|
|
switch statement.
|
|
|
|
Overall, please keep in mind that the debugger is often used as a last
|
|
resort, and a crash in the debugger is rarely appreciated by the
|
|
end-user.
|