dash/contrib/devtools
W. J. van der Laan 8ca3005a91 Merge bitcoin/bitcoin#22645: scripts: prevent GCC optimising test symbols in test-symbol-check
5449d44e37982fcd5251fd47873c5f7d34c39fc9 scripts: prevent GCC optimising test symbols in test-symbol-check (fanquake)

Pull request description:

  I noticed in #22381 that when the test-symbol-check target was being built with Clang and run in the CI it would fail due to using a too-new version of `pow` (used [here](d67330d112/contrib/devtools/test-symbol-check.py (L85))). Our CIs use Focal (glibc 2.31) and the version of `pow` was the optimized version introduced in [glibc 2.29](https://lwn.net/Articles/778286/):
  ```bash
  * Optimized generic exp, exp2, log, log2, pow, sinf, cosf, sincosf and tanf.
  ```
  This made sense, except for that if it was failing when built using Clang, why hadn't it also been failing when being built with GCC?

  Turns out GCC is optimizing away that call to `pow` at all optimization levels, including `-O0`, see: https://godbolt.org/z/53MhzMxT7, and this has been the case forever, or at least since GCC 5.x. Clang on the other hand, will only optimize away the `pow` call at `-O1` and `-O2`, not `-O0`: https://godbolt.org/z/Wbnqj3q6c. Thus when this test was built with Clang (we don't pass `-O` so we default to `-O0`) it was failing in the CI environment, because it would actually have a call to the "new" `pow`.

  Avoid this issue by using a symbol that won't be optimized away, or that we are unlikely to ever have versioning issues with.

ACKs for top commit:
  laanwj:
    ACK 5449d44e37982fcd5251fd47873c5f7d34c39fc9

Tree-SHA512: 3a26c5c3a5f2905fd0dd90892470e241ba625c0af3be2629d06d5da3a97534c1d6a55b796bbdd41e2e6a26a8fab7d981b98c45d4238565b0eb7edf3c5da02007
2023-04-16 23:40:59 +03:00
..
circular-dependencies.py perf: enable more multi-threading and caching in linters (#4807) 2022-04-27 21:14:40 +03:00
clang-format-diff.py Merge #14903: tests: Handle ImportError explicitly, improve comparisons against None 2021-10-08 19:13:52 +05:30
copyright_header.py chore: run copyright_header.py update 2023-01-13 00:49:04 +03:00
gen-manpages.sh Merge #17691: doc: Add missed copyright headers 2022-04-02 09:19:20 +05:30
github-merge.py Merge #16223: devtools: Fetch and display ACKs at sign-off time in github-merge 2021-09-12 14:15:11 -04:00
optimize-pngs.py
pixie.py merge bitcoin#22244: Correctly extract symbol versions in symbol-check 2023-01-18 19:02:39 -06:00
README.md Merge #18395: scripts: add PE dylib checking to symbol-check.py 2023-03-26 16:50:26 -05:00
security-check.py merge bitcoin#20434: Parse ELF directly for symbol and security checks 2023-01-18 19:02:39 -06:00
split-debug.sh.in
symbol-check.py Merge #18395: scripts: add PE dylib checking to symbol-check.py 2023-03-26 16:50:26 -05:00
test_deterministic_coverage.sh Merge #16878: Fix non-deterministic coverage of test DoS_mapOrphans 2022-09-03 10:43:14 -05:00
test-security-check.py merge bitcoin#19525: add -Wl,-z,separate-code to hardening flags 2023-01-18 19:02:39 -06:00
test-symbol-check.py Merge bitcoin/bitcoin#22645: scripts: prevent GCC optimising test symbols in test-symbol-check 2023-04-16 23:40:59 +03:00
update-css-files.py
update-translations.py Merge #14903: tests: Handle ImportError explicitly, improve comparisons against None 2021-10-08 19:13:52 +05:30
utxo_snapshot.sh merge bitcoin#16899: UTXO snapshot creation (dumptxoutset) 2022-05-23 10:38:33 +05:30

Contents

This directory contains tools for developers working on this repository.

clang-format-diff.py

A script to format unified git diffs according to .clang-format.

Requires clang-format, installed e.g. via brew install clang-format on macOS, or sudo apt install clang-format on Debian/Ubuntu.

For instance, to format the last commit with 0 lines of context, the script should be called from the git root folder as follows.

git diff -U0 HEAD~1.. | ./contrib/devtools/clang-format-diff.py -p1 -i -v

copyright_header.py

Provides utilities for managing copyright headers of The Dash Core developers in repository source files. It has three subcommands:

$ ./copyright_header.py report <base_directory> [verbose]
$ ./copyright_header.py update <base_directory>
$ ./copyright_header.py insert <file>

Running these subcommands without arguments displays a usage string.

Produces a report of all copyright header notices found inside the source files of a repository. Useful to quickly visualize the state of the headers. Specifying verbose will list the full filenames of files of each category.

Updates all the copyright headers of The Dash Core developers which were changed in a year more recent than is listed. For example:

// Copyright (c) <firstYear>-<lastYear> The Dash Core developers

will be updated to:

// Copyright (c) <firstYear>-<lastModifiedYear> The Dash Core developers

where <lastModifiedYear> is obtained from the git log history.

This subcommand also handles copyright headers that have only a single year. In those cases:

// Copyright (c) <year> The Dash Core developers

will be updated to:

// Copyright (c) <year>-<lastModifiedYear> The Dash Core developers

where the update is appropriate.

Inserts a copyright header for The Dash Core developers at the top of the file in either Python or C++ style as determined by the file extension. If the file is a Python file and it has #! starting the first line, the header is inserted in the line below it.

The copyright dates will be set to be <year_introduced>-<current_year> where <year_introduced> is according to the git log history. If <year_introduced> is equal to <current_year>, it will be set as a single year rather than two hyphenated years.

If the file already has a copyright for The Dash Core developers, the script will exit.

gen-manpages.sh

A small script to automatically create manpages in ../../doc/man by running the release binaries with the -help option. This requires help2man which can be found at: https://www.gnu.org/software/help2man/

With in-tree builds this tool can be run from any directory within the repostitory. To use this tool with out-of-tree builds set BUILDDIR. For example:

BUILDDIR=$PWD/build contrib/devtools/gen-manpages.sh

github-merge.py

A small script to automate merging pull-requests securely and sign them with GPG.

For example:

./github-merge.py 3077

(in any git repository) will help you merge pull request #3077 for the dashpay/dash repository.

What it does:

  • Fetch master and the pull request.
  • Locally construct a merge commit.
  • Show the diff that merge results in.
  • Ask you to verify the resulting source tree (so you can do a make check or whatever).
  • Ask you whether to GPG sign the merge commit.
  • Ask you whether to push the result upstream.

This means that there are no potential race conditions (where a pullreq gets updated while you're reviewing it, but before you click merge), and when using GPG signatures, that even a compromised GitHub couldn't mess with the sources.

Setup

Configuring the github-merge tool for the Dash Core repository is done in the following way:

git config githubmerge.repository dashpay/dash
git config githubmerge.testcmd "make -j4 check" (adapt to whatever you want to use for testing)
git config --global user.signingkey mykeyid

Authentication (optional)

The API request limit for unauthenticated requests is quite low, but the limit for authenticated requests is much higher. If you start running into rate limiting errors it can be useful to set an authentication token so that the script can authenticate requests.

  • First, go to Personal access tokens.
  • Click 'Generate new token'.
  • Fill in an arbitrary token description. No further privileges are needed.
  • Click the Generate token button at the bottom of the form.
  • Copy the generated token (should be a hexadecimal string)

Then do:

git config --global user.ghtoken "pasted token"

Create and verify timestamps of merge commits

To create or verify timestamps on the merge commits, install the OpenTimestamps client via pip3 install opentimestamps-client. Then, download the gpg wrapper ots-git-gpg-wrapper.sh and set it as git's gpg.program. See the ots git integration documentation for further details.

optimize-pngs.py

A script to optimize png files in the dash repository (requires pngcrush).

security-check.py and test-security-check.py

Perform basic security checks on a series of executables.

symbol-check.py

A script to check that the executables produced by Gitian only contain certain symbols and are only linked against allowed libraries.

For Linux this means checking for allowed gcc, glibc and libstdc++ version symbols. This makes sure they are still compatible with the minimum supported distribution versions.

For macOS and Windows we check that the executables are only linked against libraries we allow.

Example usage after a Gitian build:

find ../gitian-builder/build -type f -executable | xargs python3 contrib/devtools/symbol-check.py

If no errors occur the return value will be 0 and the output will be empty.

If there are any errors the return value will be 1 and output like this will be printed:

.../64/test_dash: symbol memcpy from unsupported version GLIBC_2.14
.../64/test_dash: symbol __fdelt_chk from unsupported version GLIBC_2.15
.../64/test_dash: symbol std::out_of_range::~out_of_range() from unsupported version GLIBCXX_3.4.15
.../64/test_dash: symbol _ZNSt8__detail15_List_nod from unsupported version GLIBCXX_3.4.15

update-translations.py

Run this script from the root of the repository to update all translations from transifex. It will do the following automatically:

  • fetch all translations
  • post-process them into valid and committable format
  • add missing translations to the build system (TODO)

See doc/translation-process.md for more information.

circular-dependencies.py

Run this script from the root of the source tree (src/) to find circular dependencies in the source code. This looks only at which files include other files, treating the .cpp and .h file as one unit.

Example usage:

cd .../src
../contrib/devtools/circular-dependencies.py {*,*/*,*/*/*}.{h,cpp}