Skip to content

Commit 8a92f2c

Browse files
committed
added separate program to test stack trace [skip ci]
1 parent 524a5e8 commit 8a92f2c

4 files changed

Lines changed: 93 additions & 2 deletions

File tree

.github/workflows/CI-unixish.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ jobs:
420420
- name: Test Signalhandler
421421
run: |
422422
cmake -S . -B cmake.output.signal -G "Unix Makefiles" -DBUILD_TESTS=On
423-
cmake --build cmake.output.signal --target test-signalhandler -- -j$(nproc)
423+
cmake --build cmake.output.signal --target test-signalhandler test-stacktrace -- -j$(nproc)
424424
cp cmake.output.signal/bin/test-s* .
425425
python3 -m pytest -Werror --strict-markers -vv test/signal/test-*.py
426426

test/signal/CMakeLists.txt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,14 @@ target_include_directories(test-signalhandler PRIVATE ${PROJECT_SOURCE_DIR}/cli
77
target_compile_options_safe(test-signalhandler -Wno-missing-declarations)
88
target_compile_options_safe(test-signalhandler -Wno-missing-prototypes)
99
# required for backtrace() to produce function names
10-
target_compile_options(test-signalhandler PRIVATE -rdynamic)
10+
target_compile_options(test-signalhandler PRIVATE -rdynamic)
11+
12+
add_executable(test-stacktrace
13+
test-stacktrace.cpp
14+
${PROJECT_SOURCE_DIR}/cli/stacktrace.cpp)
15+
target_include_directories(test-stacktrace PRIVATE ${PROJECT_SOURCE_DIR}/cli ${PROJECT_SOURCE_DIR}/lib)
16+
# names for static functions are omitted from trace
17+
target_compile_options_safe(test-stacktrace -Wno-missing-declarations)
18+
target_compile_options_safe(test-stacktrace -Wno-missing-prototypes)
19+
# required for backtrace() to produce function names
20+
target_link_options(test-stacktrace PRIVATE -rdynamic)

test/signal/test-stacktrace.cpp

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
/*
2+
* Cppcheck - A tool for static C/C++ code analysis
3+
* Copyright (C) 2007-2023 Cppcheck team.
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
19+
#include "stacktrace.h"
20+
21+
// static functions are omitted from trace
22+
23+
void my_func_2()
24+
{
25+
print_stacktrace(stdout, 0, true, -1);
26+
}
27+
28+
void my_func()
29+
{
30+
my_func_2();
31+
}
32+
33+
int main(int argc, const char * const argv[])
34+
{
35+
(void)argc;
36+
(void)argv;
37+
//if (argc != 2)
38+
// return 1;
39+
40+
my_func();
41+
42+
return 0;
43+
}

test/signal/test-stacktrace.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import subprocess
2+
import os
3+
import sys
4+
5+
def _lookup_cppcheck_exe(exe_name):
6+
# path the script is located in
7+
script_path = os.path.dirname(os.path.realpath(__file__))
8+
9+
if sys.platform == "win32":
10+
exe_name += ".exe"
11+
12+
for base in (script_path + '/../../', './'):
13+
for path in ('', 'bin/', 'bin/debug/'):
14+
exe_path = base + path + exe_name
15+
if os.path.isfile(exe_path):
16+
print("using '{}'".format(exe_path))
17+
return exe_path
18+
19+
return None
20+
21+
def _call_process():
22+
exe = _lookup_cppcheck_exe('test-stacktrace')
23+
if exe is None:
24+
raise Exception('executable not found')
25+
p = subprocess.Popen([exe], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
26+
comm = p.communicate()
27+
stdout = comm[0].decode(encoding='utf-8', errors='ignore').replace('\r\n', '\n')
28+
stderr = comm[1].decode(encoding='utf-8', errors='ignore').replace('\r\n', '\n')
29+
return p.returncode, stdout, stderr
30+
31+
32+
def test_stack():
33+
exitcode, stdout, stderr = _call_process()
34+
assert stderr == ''
35+
lines = stdout.splitlines()
36+
assert lines[0] == 'Callstack:'
37+
assert lines[1].endswith('my_func_2()')
38+
assert lines[2].endswith('my_func()')

0 commit comments

Comments
 (0)