Skip to content

Commit 9fdc8af

Browse files
dongcarlfanquake
authored andcommitted
devtools: Improve *-check.py tool detection
This is important to make sure that we're not testing tools different from the one we're building with. Introduce determine_wellknown_cmd, which encapsulates how we should handle well-known tools specification (IFS splitting, env override, etc.).
1 parent bda62ea commit 9fdc8af

File tree

6 files changed

+50
-24
lines changed

6 files changed

+50
-24
lines changed

Makefile.am

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ DIST_SHARE = \
5858

5959
BIN_CHECKS=$(top_srcdir)/contrib/devtools/symbol-check.py \
6060
$(top_srcdir)/contrib/devtools/security-check.py \
61+
$(top_srcdir)/contrib/devtools/utils.py \
6162
$(top_srcdir)/contrib/devtools/pixie.py
6263

6364
WINDOWS_PACKAGING = $(top_srcdir)/share/pixmaps/bitcoin.ico \
@@ -366,14 +367,14 @@ clean-local: clean-docs
366367

367368
test-security-check:
368369
if TARGET_DARWIN
369-
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_MACHO
370-
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_MACHO
370+
$(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_MACHO
371+
$(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_MACHO
371372
endif
372373
if TARGET_WINDOWS
373-
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_PE
374-
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_PE
374+
$(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_PE
375+
$(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_PE
375376
endif
376377
if TARGET_LINUX
377-
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_ELF
378-
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_ELF
378+
$(AM_V_at) CC='$(CC)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-security-check.py TestSecurityChecks.test_ELF
379+
$(AM_V_at) CC='$(CC)' CPPFILT='$(CPPFILT)' $(PYTHON) $(top_srcdir)/contrib/devtools/test-symbol-check.py TestSymbolChecks.test_ELF
379380
endif

contrib/devtools/symbol-check.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@
1212
'''
1313
import subprocess
1414
import sys
15-
import os
1615
from typing import List, Optional
1716

1817
import lief
1918
import pixie
2019

20+
from utils import determine_wellknown_cmd
21+
2122
# Debian 8 (Jessie) EOL: 2020. https://wiki.debian.org/DebianReleases#Production_Releases
2223
#
2324
# - g++ version 4.9.2 (https://packages.debian.org/search?suite=jessie&arch=any&searchon=names&keywords=g%2B%2B)
@@ -60,7 +61,6 @@
6061
'_edata', '_end', '__end__', '_init', '__bss_start', '__bss_start__', '_bss_end__', '__bss_end__', '_fini', '_IO_stdin_used', 'stdin', 'stdout', 'stderr',
6162
'environ', '_environ', '__environ',
6263
}
63-
CPPFILT_CMD = os.getenv('CPPFILT', '/usr/bin/c++filt')
6464

6565
# Allowed NEEDED libraries
6666
ELF_ALLOWED_LIBRARIES = {
@@ -140,7 +140,7 @@ class CPPFilt(object):
140140
Use a pipe to the 'c++filt' command.
141141
'''
142142
def __init__(self):
143-
self.proc = subprocess.Popen(CPPFILT_CMD, stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True)
143+
self.proc = subprocess.Popen(determine_wellknown_cmd('CPPFILT', 'c++filt'), stdin=subprocess.PIPE, stdout=subprocess.PIPE, universal_newlines=True)
144144

145145
def __call__(self, mangled):
146146
self.proc.stdin.write(mangled + '\n')

contrib/devtools/test-security-check.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import subprocess
1010
import unittest
1111

12+
from utils import determine_wellknown_cmd
13+
1214
def write_testcode(filename):
1315
with open(filename, 'w', encoding="utf8") as f:
1416
f.write('''
@@ -25,15 +27,15 @@ def clean_files(source, executable):
2527
os.remove(executable)
2628

2729
def call_security_check(cc, source, executable, options):
28-
subprocess.run([cc,source,'-o',executable] + options, check=True)
30+
subprocess.run([*cc,source,'-o',executable] + options, check=True)
2931
p = subprocess.run(['./contrib/devtools/security-check.py',executable], stdout=subprocess.PIPE, universal_newlines=True)
3032
return (p.returncode, p.stdout.rstrip())
3133

3234
class TestSecurityChecks(unittest.TestCase):
3335
def test_ELF(self):
3436
source = 'test1.c'
3537
executable = 'test1'
36-
cc = 'gcc'
38+
cc = determine_wellknown_cmd('CC', 'gcc')
3739
write_testcode(source)
3840

3941
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-zexecstack','-fno-stack-protector','-Wl,-znorelro','-no-pie','-fno-PIE', '-Wl,-z,separate-code']),
@@ -54,7 +56,7 @@ def test_ELF(self):
5456
def test_PE(self):
5557
source = 'test1.c'
5658
executable = 'test1.exe'
57-
cc = 'x86_64-w64-mingw32-gcc'
59+
cc = determine_wellknown_cmd('CC', 'x86_64-w64-mingw32-gcc')
5860
write_testcode(source)
5961

6062
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--no-nxcompat','-Wl,--no-dynamicbase','-Wl,--no-high-entropy-va','-no-pie','-fno-PIE']),
@@ -73,7 +75,7 @@ def test_PE(self):
7375
def test_MACHO(self):
7476
source = 'test1.c'
7577
executable = 'test1'
76-
cc = 'clang'
78+
cc = determine_wellknown_cmd('CC', 'clang')
7779
write_testcode(source)
7880

7981
self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fno-stack-protector']),
@@ -95,4 +97,3 @@ def test_MACHO(self):
9597

9698
if __name__ == '__main__':
9799
unittest.main()
98-

contrib/devtools/test-symbol-check.py

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,13 @@
77
'''
88
import os
99
import subprocess
10+
from typing import List
1011
import unittest
1112

12-
def call_symbol_check(cc, source, executable, options):
13-
subprocess.run([cc,source,'-o',executable] + options, check=True)
13+
from utils import determine_wellknown_cmd
14+
15+
def call_symbol_check(cc: List[str], source, executable, options):
16+
subprocess.run([*cc,source,'-o',executable] + options, check=True)
1417
p = subprocess.run(['./contrib/devtools/symbol-check.py',executable], stdout=subprocess.PIPE, universal_newlines=True)
1518
os.remove(source)
1619
os.remove(executable)
@@ -20,7 +23,7 @@ class TestSymbolChecks(unittest.TestCase):
2023
def test_ELF(self):
2124
source = 'test1.c'
2225
executable = 'test1'
23-
cc = 'gcc'
26+
cc = determine_wellknown_cmd('CC', 'gcc')
2427

2528
# renameat2 was introduced in GLIBC 2.28, so is newer than the upper limit
2629
# of glibc for all platforms
@@ -82,7 +85,7 @@ def test_ELF(self):
8285
def test_MACHO(self):
8386
source = 'test1.c'
8487
executable = 'test1'
85-
cc = 'clang'
88+
cc = determine_wellknown_cmd('CC', 'clang')
8689

8790
with open(source, 'w', encoding="utf8") as f:
8891
f.write('''
@@ -132,7 +135,7 @@ def test_MACHO(self):
132135
def test_PE(self):
133136
source = 'test1.c'
134137
executable = 'test1.exe'
135-
cc = 'x86_64-w64-mingw32-gcc'
138+
cc = determine_wellknown_cmd('CC', 'x86_64-w64-mingw32-gcc')
136139

137140
with open(source, 'w', encoding="utf8") as f:
138141
f.write('''
@@ -182,4 +185,3 @@ def test_PE(self):
182185

183186
if __name__ == '__main__':
184187
unittest.main()
185-

contrib/devtools/utils.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) 2021 The Bitcoin Core developers
3+
# Distributed under the MIT software license, see the accompanying
4+
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
5+
'''
6+
Common utility functions
7+
'''
8+
import shutil
9+
import sys
10+
import os
11+
from typing import List
12+
13+
14+
def determine_wellknown_cmd(envvar, progname) -> List[str]:
15+
maybe_env = os.getenv(envvar)
16+
maybe_which = shutil.which(progname)
17+
if maybe_env:
18+
return maybe_env.split(' ') # Well-known vars are often meant to be word-split
19+
elif maybe_which:
20+
return [ maybe_which ]
21+
else:
22+
sys.exit(f"{progname} not found")

src/Makefile.am

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -814,23 +814,23 @@ clean-local:
814814
check-symbols: $(bin_PROGRAMS)
815815
if TARGET_DARWIN
816816
@echo "Checking macOS dynamic libraries..."
817-
$(AM_V_at) OTOOL=$(OTOOL) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
817+
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
818818
endif
819819

820820
if TARGET_WINDOWS
821821
@echo "Checking Windows dynamic libraries..."
822-
$(AM_V_at) OBJDUMP=$(OBJDUMP) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
822+
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
823823
endif
824824

825825
if TARGET_LINUX
826826
@echo "Checking glibc back compat..."
827-
$(AM_V_at) CPPFILT=$(CPPFILT) $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
827+
$(AM_V_at) CPPFILT='$(CPPFILT)' $(PYTHON) $(top_srcdir)/contrib/devtools/symbol-check.py $(bin_PROGRAMS)
828828
endif
829829

830830
check-security: $(bin_PROGRAMS)
831831
if HARDEN
832832
@echo "Checking binary security..."
833-
$(AM_V_at) OBJDUMP=$(OBJDUMP) OTOOL=$(OTOOL) $(PYTHON) $(top_srcdir)/contrib/devtools/security-check.py $(bin_PROGRAMS)
833+
$(AM_V_at) $(PYTHON) $(top_srcdir)/contrib/devtools/security-check.py $(bin_PROGRAMS)
834834
endif
835835

836836
libbitcoin_ipc_mpgen_input = \

0 commit comments

Comments
 (0)