Skip to content

Commit 68504a0

Browse files
authored
bisect: handle crashes as "bad" / added hot-patch for 1.88/1.89 compilation failures / added expected output as optional parameter (#4804)
1 parent 8f5f06a commit 68504a0

4 files changed

Lines changed: 73 additions & 22 deletions

File tree

tools/bisect/README.md

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,39 @@
11
# Bisecting
22

3-
NOTE: THIS IS WORK IN PROGRESS
3+
`bisect.sh` is a script to bisect regressions in Cppcheck utilizing `git-bisect`.
44

5-
`bisect.sh` is a script to bisect issues.
5+
To learn more about bisecting please refer to https://git-scm.com/docs/git-bisect.
66

77
## Command
88

99
```
10-
./bisect.sh <hash-good> <hash-bad> "<cppcheck-options>"
10+
./bisect.sh <hash-good> <hash-bad> "<cppcheck-options>" "[expected]"
1111
```
1212

13-
`hash-good` - the last known good commit hash - in case of daca it is the last tagged minor release (not patch release - i.e. 2.x)
14-
`hash-bad` - the known bad commit hash - in case of daca the one from the `head-info:` line
15-
`cppcheck-options` - the options for the Cppcheck invokation - in case of daca the ones from the `cppcheck-options:` line and the path to the folder/file to scan
13+
`hash-good` the latest known good commit hash or tag<br/>
14+
`hash-bad` the earliest known bad commit hash or tag<br/>
15+
`cppcheck-options` the options for the Cppcheck invokatio<br/>
16+
`expected` (optional) a string that is expected in the output. Will be used instead of the exitcode
1617

1718
If possible use `main` as the function to test stuff with since it won't emit an `unusedFunction` warning.
1819

19-
## Bisecting scan time regressions
20-
21-
We use daca to track differences in scan time. An overview of regressions in scan time can be found at http://cppcheck1.osuosl.org:8000/time_gt.html.
22-
23-
You need to download the archive as specified by the second line in the output and extract it.
24-
25-
If the overall scan time regressed you need to specify the whole folder.
20+
## Bisecting result regressions
2621

27-
If a timeout (potential hang) was introduced you can simply specify the file from `error: Internal error: Child process crashed with signal 15 [cppcheckError]`.
22+
Results regressions are being bisected based on the `--error-exitcode=` result.
2823

24+
If nothing is found the result will be `0` and it is treated as a _good_ commit.<br/>
25+
If a finding occurs the result will be `1` which is treated as a _bad_ commit.<br/>
26+
If a crash occurs it is treated as a _bad_ commit.
2927

30-
## Bisecting result regressions
28+
You can also bisect based on expected output via the `expected` parameter.
3129

32-
Results regressions are being bisected based on the `--error-exitcode=` result.
33-
If nothing is found the result will be `0` and it is treated as a _good_ commit.
34-
If a finding occurs the result will be `1` which is treated as a _bad_ commit.
30+
If the given string is found in the output it is treated as a _good_ commit.<br/>
31+
If the given string is _not_ found in the output it is treated as a _bad_ commit.<br/>
32+
If a crash occurs it is treated as a _bad_ commit.
3533

3634
### False positive
3735

38-
Provide a code sample which will trigger the false postive.
36+
Provide a code sample which will trigger a single(!) false postive only. Trying to bisect multiple issues at the same time will most likely result in an incorrect result (see below).
3937

4038
```cpp
4139
// cppcheck-suppress unusedFunction
@@ -45,8 +43,16 @@ static void f()
4543
}
4644
```
4745

46+
```
47+
./bisect.sh <hash-good> <hash-bad> "<cppcheck-options>"
48+
```
49+
50+
After the bisecting check the output to make sure that only expected false positive and no additional finding was reported for the _bad_ commits. Any other finding will also cause the commit to be marked as _bad_ leading to an incorrect result.
51+
4852
### False negative
4953

54+
#### Via suppression
55+
5056
Provide a code sample which will trigger a `unmatchedSuppression`.
5157

5258
```cpp
@@ -58,15 +64,53 @@ static void f()
5864
}
5965
```
6066

67+
```
68+
./bisect.sh <hash-good> <hash-bad> "<cppcheck-options>"
69+
```
70+
71+
#### Via output
72+
73+
```cpp
74+
static void f()
75+
{
76+
int i;
77+
}
78+
```
79+
80+
Provide the expected error ID (`unreadVariable`) as the `expected` parameter.
81+
82+
```
83+
./bisect.sh <hash-good> <hash-bad> "<cppcheck-options>" "unreadVariable"
84+
```
85+
86+
## Bisecting scan time regressions
87+
88+
We use daca@home to track differences in scan time. An overview of regressions in scan time can be found at http://cppcheck1.osuosl.org:8000/time_gt.html.
89+
90+
You need to download the archive as specified by the second line in the output and extract it.
91+
92+
If the overall scan time regressed you need to specify the whole folder.
93+
94+
If a timeout (potential hang) was introduced you can simply specify the file from `error: Internal error: Child process crashed with signal 15 [cppcheckError]`.
95+
6196
## Notes
6297

63-
### Compilation issues:
98+
### Bisecting daca@home issues
99+
100+
Use the following data as respective parameters:
101+
102+
`hash-good` the latest tagged release - the second value from the `cppcheck:` line<br/>
103+
`hash-bad` the commit hash from the `head-info:` line<br/>
104+
`cppcheck-options` the `cppcheck-options:` line and the path to the folder/file to scan<br/>
105+
106+
### Known compilation issues:
64107

65108
- 2.5 and before can only be built with GCC<=10 because of missing includes caused by cleanups within the standard headers. You need to specify `CXX=g++-10`.
66109
- 1.88 and 1.89 cannot be compiled:
67110
```
68111
make: python: No such file or directory
69112
```
113+
RESOLVED: a hot-patch is applied before compilation.
70114
- 1.39 to 1.49 (possibly more versions - 1.54 and up work) cannot be compiled:
71115
```
72116
lib/mathlib.cpp:70:42: error: invalid conversion from ‘char’ to ‘char**’ [-fpermissive]

tools/bisect/bisect.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ set -x
77
hash_good=$1
88
hash_bad=$2
99
options=$3
10+
expected=$4
1011

1112
# TODO: verify "good" commit happened before "bad" commit
1213

1314
hang=0
14-
expected=""
1515

1616
script_dir="$(dirname "$(realpath "$0")")"
1717

tools/bisect/bisect_common.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,11 @@ def build_cppcheck(bisect_path):
2020
if os.path.exists(os.path.join(bisect_repo_dir, 'cppcheck')):
2121
os.remove(os.path.join(bisect_repo_dir, 'cppcheck'))
2222

23+
# for versions 1.88 and 1.89
24+
print('patching Makefile')
25+
subprocess.check_call(['sed', '-i', 's/shell python /shell python3 /g', os.path.join(bisect_repo_dir, 'Makefile')])
26+
27+
# for versions between 2.0 and 2.2
2328
print('patching cli/cppcheckexecutor.cpp')
2429
subprocess.check_call(['sed', '-i', 's/SIGSTKSZ/32768/g', os.path.join(bisect_repo_dir, 'cli', 'cppcheckexecutor.cpp')])
2530

tools/bisect/bisect_res.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def run(cppcheck_path, options):
1717
# signals are report as negative exitcode (e.g. SIGSEGV -> -11)
1818
if p.returncode < 0:
1919
print('crash')
20-
return None, None, None
20+
return p.returncode, stderr, stdout
2121
print('done')
2222
return p.returncode, stderr, stdout
2323

@@ -54,6 +54,8 @@ def run(cppcheck_path, options):
5454
# if no ec is set we encountered an unexpected error
5555
if run_ec is None:
5656
sys.exit(EC_SKIP) # error occured
57+
elif run_ec < 0:
58+
sys.exit(EC_BAD) # crash occured
5759

5860
# check output for expected string
5961
if expected is not None:

0 commit comments

Comments
 (0)