-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
added separate program to test signal handler / cleaned up and improv…
…ed stacktrace generation
- Loading branch information
Showing
8 changed files
with
220 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
add_executable(test-signalhandler | ||
test-signalhandler.cpp | ||
${PROJECT_SOURCE_DIR}/cli/signalhandler.cpp | ||
${PROJECT_SOURCE_DIR}/cli/stacktrace.cpp) | ||
target_include_directories(test-signalhandler PRIVATE ${PROJECT_SOURCE_DIR}/cli ${PROJECT_SOURCE_DIR}/lib) | ||
# names for static functions are omitted from trace | ||
target_compile_options_safe(test-signalhandler -Wno-missing-declarations) | ||
target_compile_options_safe(test-signalhandler -Wno-missing-prototypes) | ||
# required for backtrace() to produce function names | ||
target_link_options(test-signalhandler PRIVATE -rdynamic) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
/* | ||
* Cppcheck - A tool for static C/C++ code analysis | ||
* Copyright (C) 2007-2024 Cppcheck team. | ||
* | ||
* This program is free software: you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License as published by | ||
* the Free Software Foundation, either version 3 of the License, or | ||
* (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU General Public License | ||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
*/ | ||
|
||
#include "signalhandler.h" | ||
|
||
#include <cassert> | ||
#include <cfenv> | ||
#include <cstring> | ||
|
||
NORETURN void my_assert() | ||
{ | ||
assert(false); | ||
} | ||
|
||
NORETURN void my_abort() | ||
{ | ||
abort(); | ||
} | ||
|
||
void my_segv() | ||
{ | ||
// cppcheck-suppress nullPointer | ||
++*(int*)nullptr; | ||
} | ||
|
||
void my_fpe() | ||
{ | ||
feenableexcept(FE_ALL_EXCEPT); // TODO: check result | ||
std::feraiseexcept(FE_UNDERFLOW | FE_DIVBYZERO); // TODO: check result | ||
// TODO: to generate this via code | ||
} | ||
|
||
int main(int argc, const char * const argv[]) | ||
{ | ||
if (argc != 2) | ||
return 1; | ||
|
||
register_signal_handler(); | ||
|
||
if (strcmp(argv[1], "assert") == 0) | ||
my_assert(); | ||
else if (strcmp(argv[1], "abort") == 0) | ||
my_abort(); | ||
else if (strcmp(argv[1], "fpe") == 0) | ||
my_fpe(); | ||
else if (strcmp(argv[1], "segv") == 0) | ||
my_segv(); | ||
|
||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
import subprocess | ||
import os | ||
import sys | ||
import pytest | ||
|
||
def _lookup_cppcheck_exe(exe_name): | ||
# path the script is located in | ||
script_path = os.path.dirname(os.path.realpath(__file__)) | ||
|
||
if sys.platform == "win32": | ||
exe_name += ".exe" | ||
|
||
for base in (script_path + '/../../', './'): | ||
for path in ('', 'bin/', 'bin/debug/'): | ||
exe_path = base + path + exe_name | ||
if os.path.isfile(exe_path): | ||
print("using '{}'".format(exe_path)) | ||
return exe_path | ||
|
||
return None | ||
|
||
def _call_process(arg): | ||
exe = _lookup_cppcheck_exe('test-signalhandler') | ||
if exe is None: | ||
raise Exception('executable not found') | ||
p = subprocess.Popen([exe, arg], stdout=subprocess.PIPE, stderr=subprocess.PIPE) | ||
comm = p.communicate() | ||
stdout = comm[0].decode(encoding='utf-8', errors='ignore').replace('\r\n', '\n') | ||
stderr = comm[1].decode(encoding='utf-8', errors='ignore').replace('\r\n', '\n') | ||
return p.returncode, stdout, stderr | ||
|
||
|
||
def test_assert(): | ||
exitcode, stdout, stderr = _call_process('assert') | ||
assert stderr.endswith("test-signalhandler.cpp:27: void my_assert(): Assertion `false' failed.\n"), stderr | ||
lines = stdout.splitlines() | ||
assert lines[0] == 'Internal error: cppcheck received signal SIGABRT - abort or assertion' | ||
assert lines[1] == 'Callstack:' | ||
assert lines[2].endswith('my_abort()'), lines[2] # TODO: wrong function | ||
assert lines[len(lines)-1] == 'Please report this to the cppcheck developers!' | ||
|
||
|
||
def test_abort(): | ||
exitcode, stdout, stderr = _call_process('abort') | ||
lines = stdout.splitlines() | ||
assert lines[0] == 'Internal error: cppcheck received signal SIGABRT - abort or assertion' | ||
assert lines[1] == 'Callstack:' | ||
assert lines[2].endswith('my_segv()'), lines[2] # TODO: wrong function | ||
assert lines[len(lines)-1] == 'Please report this to the cppcheck developers!' | ||
|
||
|
||
def test_segv(): | ||
exitcode, stdout, stderr = _call_process('segv') | ||
assert stderr == '' | ||
lines = stdout.splitlines() | ||
assert lines[0] == 'Internal error: cppcheck received signal SIGSEGV - SEGV_MAPERR (reading at 0x0).' | ||
assert lines[1] == 'Callstack:' | ||
assert lines[2].endswith('my_segv()'), lines[2] # TODO: wrong function | ||
assert lines[len(lines)-1] == 'Please report this to the cppcheck developers!' | ||
|
||
|
||
# TODO: make this work | ||
@pytest.mark.skip | ||
def test_fpe(): | ||
exitcode, stdout, stderr = _call_process('fpe') | ||
assert stderr == '' | ||
lines = stdout.splitlines() | ||
assert lines[0].startswith('Internal error: cppcheck received signal SIGFPE - FPE_FLTDIV (at 0x7f'), lines[0] | ||
assert lines[0].endswith(').'), lines[0] | ||
assert lines[1] == 'Callstack:' | ||
assert lines[2].endswith('my_fpe()'), lines[2] | ||
assert lines[len(lines)-1] == 'Please report this to the cppcheck developers!' |