commit b80fd14932e7c4780ab68d14cef6e20ff4daf836 Author: Yuri Date: Fri Apr 18 12:21:18 2025 +0400 initial version diff --git a/README.md b/README.md new file mode 100644 index 0000000..4bd7ad0 --- /dev/null +++ b/README.md @@ -0,0 +1,34 @@ +# Подключение к Keil статического анализатора PVS-Studio + +## Требования к установке +- установленный MDK-Arm v.5 +- установленный PVS-Studio (https://pvs-studio.ru/ru/pvs-studio/download/) +- установленный git + +## Установка +- в каталоге с проектом .uvprojx создать папки PVS-STUDIO и scripts +- скопировать содержимое папки scripts +- исправить путь к git в переменной GIT_BASH_PATH внутри файлов: + check_project.bat +- исправить путь к PVS-Studio в переменной PVS_STUDIO_PATH внутри файлов: + CLMonitorDumpFilterLauncher_uVision.bat + view_pvs_log.bat +- при необходимости отключения отдельных предупреждений - внести их список + в файл ignore_warnings.pvsconfig +- в Keil отключить многопоточную компиляцию (Edit -> Configuration -> Other -> + поставить галочку на Disable Parallel Build) +- в настройках проекта (Project -> Options for target -> User) прописать + команды запуска скриптов: + Before Compile C/C++ File + [+] Run 1: .\scripts\_before_compile.bat #X #E + Before Build/Rebuild + [+] Run 1: .\scripts\_before_build_dump.bat #X #P "myconfig_HVU" + где myconfig_HVU это установленное в проекте имя Target + After Build/Rebuild + [+] Run 1: .\scripts\_after_build.bat #X #P + +## Использование +- в настройках проекта (Project -> Options for target -> User) установить галочки на все 3 скрипта +- выполнить полную пересборку проекта +- если новые файлы не добавляются то галочку с Before Compile можно снять +- готовый отчет можно посмотреть в текстовом файле PVS-STUDIO/<имя target>.plog.txt diff --git a/scripts/CLMonitorDumpFilter.exe b/scripts/CLMonitorDumpFilter.exe new file mode 100644 index 0000000..ea50921 Binary files /dev/null and b/scripts/CLMonitorDumpFilter.exe differ diff --git a/scripts/CLMonitorDumpFilter.exe.config b/scripts/CLMonitorDumpFilter.exe.config new file mode 100644 index 0000000..56efbc7 --- /dev/null +++ b/scripts/CLMonitorDumpFilter.exe.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/scripts/CLMonitorDumpFilter.pdb b/scripts/CLMonitorDumpFilter.pdb new file mode 100644 index 0000000..7c7339b Binary files /dev/null and b/scripts/CLMonitorDumpFilter.pdb differ diff --git a/scripts/CLMonitorDumpFilterLauncher_uVision.bat b/scripts/CLMonitorDumpFilterLauncher_uVision.bat new file mode 100644 index 0000000..42b1fc4 --- /dev/null +++ b/scripts/CLMonitorDumpFilterLauncher_uVision.bat @@ -0,0 +1,246 @@ +@ECHO OFF +setlocal enabledelayedexpansion + +SET PVS_STUDIO_PATH="C:\Program Files (x86)\PVS-Studio\" + +REM CLMonitorDumpFilterLauncher_uVision.bat can work in three modes: 'CREATE_AND_UPDATE_DUMP', 'ADD_COMPILED_FILE' and 'FILTER_AND_ANALYZE'. +REM Expects that CLMonitor.exe is either in system Path or env. variable PVS_STUDIO_PATH is defined and contains path to it (with a slash at the end!) +REM +REM Description of launch modes: +REM - CREATE_AND_UPDATE_DUMP: this mode creates a compilation dump from a .bat file which will be created after building a project with the enabled 'batch creation' option. +REM You must run this script in this mode before using the rest modes, because that mode generates *.CompilationDump.gz file, which is needed for further work. +REM NOTE: do not forget to disable pre/post-build steps before .bat file generation. +REM - ADD_COMPILED_FILE: this mode append specified file path to content of the filter file. +REM - FILTER_AND_ANALYZE: this mode creates a new filtered dump file accourding to specified filter file. After file is created, static +REM analysis will be started on that dump. +REM +REM Parameters: +REM - -keilPath - path to UV4.exe; can be automatically obtained in Keil with #X when calling a user script +REM - -filterFile - parameter is required for 'ADD_COMPILED_FILE' and 'FILTER_AND_ANALYZE' modes. Its value is a path to filter file. +REM - -file - parameter is required for the 'ADD_COMPILED_FILE' mode. Its value is a path to a file which will be compiled. +REM - -projPath - parameter is required for the 'CREATE_AND_UPDATE_DUMP' and 'FILTER_AND_ANALYZE' modes. Its value is a path to *.uvprojx project file. +REM - -target - parameter is required for the 'CREATE_AND_UPDATE_DUMP'. Its value is the current target chosen in *.uvprojx project file. +REM - -silent - flag which is applicable for 'ADD_COMPILED_FILE' and 'FILTER_AND_ANALYZE' modes. It makes output of the script less verbose. +REM +REM Examples of usage: +REM CLMonitorDumpFilterLauncher_uVision.bat CREATE_AND_UPDATE_DUMP -projPath "D:\MDK\Boards\ST\Blinky.uvprojx" -target Release +REM CLMonitorDumpFilterLauncher_uVision.bat ADD_COMPILED_FILE -filterFile "D:\MDK\Boards\ST\PVS-STUDIO\filesToAnalysis.txt" -file "C:\Keil_v5\ARM\PACK\ARM\CMSIS\5.0.1\CMSIS\RTOS2\RTX\Source\rtx_lib.c" [-silent] +REM CLMonitorDumpFilterLauncher_uVision.bat FILTER_AND_ANALYZE -projPath "D:\MDK\Boards\ST\Blinky.uvprojx" -filterFile "D:\MDK\Boards\ST\PVS-STUDIO\filesToAnalysis.txt" [-silent] + +IF NOT "%LOCK%"=="" ( exit 0 ) + +SET SILENT_MODE=Y + +SET CLMONITOR_PATH="%PVS_STUDIO_PATH%CLMonitor.exe" +SET CLMONITOR_DUMP_FILTER_PATH="%~dp0\CLMonitorDumpFilter.exe" +echo "DUMPFILTER PATH: %CLMONITOR_DUMP_FILTER_PATH%" +SET LAUNCH_MODE=%1 + +SHIFT + +:findKeilPath + SET curArg=%1 + SET curArg1stChar=!curArg:~0,1! + + IF [!curArg1stChar!] == [-] ( + IF /i [!curArg!] == [-keilPath] ( + + IF NOT [%2] == [] ( + SET UVISION_PATH=%~2 + SHIFT & SHIFT + ) ELSE ( + ECHO No value specified for !curArg! + EXIT /b + ) + + GOTO :findKeilPath + ) + +IF "%LAUNCH_MODE%" == "ADD_COMPILED_FILE" ( + + :addCompiledFileOptionsFlag + SET curArg=%1 + SET curArg1stChar=!curArg:~0,1! + + IF [!curArg1stChar!] == [-] ( + IF /i [!curArg!] == [-filterFile] ( + + IF NOT [%2] == [] ( + SET FILTER_PATH=%~2 + SHIFT & SHIFT + ) ELSE ( + ECHO No value specified for !curArg! + EXIT /b + ) + + ) ELSE IF /i [!curArg!] == [-file] ( + + IF NOT [%2] == [] ( + SET COMPILED_FILE=%~2 + SHIFT & SHIFT + ) ELSE ( + ECHO No value specified for !curArg! + EXIT /b + ) + + ) ELSE IF /i [!curArg!] == [-silent] ( + + SET SILENT_MODE=Y + SHIFT + + ) ELSE ( + ECHO "Unexpected option or flag !curArg!" + EXIT /b + ) + GOTO :addCompiledFileOptionsFlag + ) + + IF /i [!SILENT_MODE!] == [n] ( + ECHO Writing "!COMPILED_FILE!" to the file "!FILTER_PATH!". + ) + + !CLMONITOR_DUMP_FILTER_PATH! appendSourcesList -f "!FILTER_PATH!" -s "!COMPILED_FILE!" + + GOTO :EOF +) + +IF "%LAUNCH_MODE%" == "CREATE_AND_UPDATE_DUMP" ( + + :createAndUpdateDump + SET curArg=%1 + SET curArg1stChar=!curArg:~0,1! + + IF [!curArg1stChar!] == [-] ( + IF /i [!curArg!] == [-projPath] ( + + IF NOT [%2] == [] ( + SET PROJECT_PATH=%~2 + SET PROJECT_DIR=%~dp2 + SET PROJECT_NAME=%~n2 + SET PROJECT_NAME_WITH_EXT=%~nx2 + SHIFT & SHIFT + ) ELSE ( + ECHO No value specified for !curArg! + EXIT /b + ) + + ) ELSE IF /i [!curArg!] == [-target] ( + + IF NOT [%2] == [] ( + SET TARGET=%~2 + SHIFT & SHIFT + ) ELSE ( + ECHO No value specified for !curArg! + EXIT /b + ) + + ) ELSE ( + ECHO Unexpected option !curArg! + EXIT /b + ) + GOTO :createAndUpdateDump + ) + + SET LOCK=LOCK + SET BAT_FILE_PATH="!PROJECT_DIR!!TARGET!.bat" + SET TEMP_PVS_FOLDER="!PROJECT_DIR!PVS-STUDIO\" + SET PROJECT_BACKUP_PATH="!PROJECT_DIR!PVS-STUDIO\!PROJECT_NAME_WITH_EXT!.pvs_backup" + SET FULL_DUMP="!PROJECT_DIR!PVS-STUDIO\!PROJECT_NAME!.CompilationDump.gz" + SET PROJECT_PATH="!PROJECT_PATH!" + SET BUILD_PROJECT_COMMAND=!UVISION_PATH! -b !PROJECT_PATH! -j0 + + IF NOT EXIST !TEMP_PVS_FOLDER! ( + MKDIR !TEMP_PVS_FOLDER! + ) + + ECHO Creating a backup of a project file + COPY !PROJECT_PATH! !PROJECT_BACKUP_PATH! /Y + + ECHO Enabling batch creation mode in the project file: !PROJECT_PATH! + ECHO CMD: !CLMONITOR_DUMP_FILTER_PATH! enableBatFileGeneration -p !PROJECT_PATH! + !CLMONITOR_DUMP_FILTER_PATH! enableBatFileGeneration -p !PROJECT_PATH! + + IF NOT !ERRORLEVEL! == 0 ( + ECHO Couldn't enable batch creation mode + GOTO :EOF + ) + + ECHO Building project + @ECHO ON + %BUILD_PROJECT_COMMAND% + @ECHO OFF + + ECHO Restoring project file from backup + COPY !PROJECT_BACKUP_PATH! !PROJECT_PATH! /Y + + IF !ERRORLEVEL! == 0 ( + ECHO Deleting a backup of project file + DEL !PROJECT_BACKUP_PATH! + ) ELSE ( + ECHO Couldn't restore the project file from backup + ) + + ECHO Creating dump file: !FULL_DUMP! + ECHO CMD: !CLMONITOR_DUMP_FILTER_PATH! filterDump -c !BAT_FILE_PATH! -d !FULL_DUMP! + !CLMONITOR_DUMP_FILTER_PATH! filterDump -c !BAT_FILE_PATH! -d !FULL_DUMP! + + ECHO Deleting target batch file + DEL /f !BAT_FILE_PATH! + + SET LOCK= + GOTO :EOF +) + +IF "%LAUNCH_MODE%" == "FILTER_AND_ANALYZE" ( + + :filterAndAnalyze + SET curArg=%1 + SET curArg1stChar=!curArg:~0,1! + + IF [!curArg1stChar!] == [-] ( + IF /i [!curArg!] == [-projPath] ( + + IF NOT [%2] == [] ( + SET PROJECT_PATH=%~2 + SET PROJECT_DIR=%~dp2 + SET PROJECT_NAME=%~n2 + SET PROJECT_NAME_WITH_EXT=%~nx2 + SHIFT & SHIFT + ) ELSE ( + ECHO No value specified for !curArg! + EXIT /b + ) + + ) ELSE IF /i [!curArg!] == [-filterFile] ( + + IF NOT [%2] == [] ( + SET FILTER_PATH=%2 + SHIFT & SHIFT + ) ELSE ( + ECHO No value specified for !curArg! + EXIT /b + ) + + ) ELSE IF /i [!curArg!] == [-silent] ( + SET SILENT_MODE=Y + SHIFT + ) ELSE ( + ECHO Unexpected option or flag !curArg! + EXIT /b + ) + GOTO :filterAndAnalyze + ) + + SET TEMP_PVS_FOLDER="!PROJECT_DIR!PVS-STUDIO\" + SET PROJECT_BACKUP_PATH="!PROJECT_DIR!PVS-STUDIO\!PROJECT_NAME_WITH_EXT!.pvs_backup" + SET FULL_DUMP="!PROJECT_DIR!PVS-STUDIO\!PROJECT_NAME!.CompilationDump.gz" + SET FILTERED_DUMP="!PROJECT_DIR!PVS-STUDIO\!PROJECT_NAME!.FilteredCompilationDump.gz" + SET OUTPUT_LOG="!PROJECT_DIR!PVS-STUDIO\!PROJECT_NAME!.plog" + + ECHO Creating filtered dump: !FILTERED_DUMP! + !CLMONITOR_DUMP_FILTER_PATH! filterDump -c !FULL_DUMP! -d !FILTERED_DUMP! -f !FILTER_PATH! + + REM Analysis itself will be performed by a separate script + + ) +) diff --git a/scripts/CommandLine.dll b/scripts/CommandLine.dll new file mode 100644 index 0000000..d5497ef Binary files /dev/null and b/scripts/CommandLine.dll differ diff --git a/scripts/CredentialManagement.dll b/scripts/CredentialManagement.dll new file mode 100644 index 0000000..004dbe1 Binary files /dev/null and b/scripts/CredentialManagement.dll differ diff --git a/scripts/_after_build.bat b/scripts/_after_build.bat new file mode 100644 index 0000000..7af78bf --- /dev/null +++ b/scripts/_after_build.bat @@ -0,0 +1,13 @@ +@echo off + +rem Expects two arguments, first - path to UV4.exe (can be obtained as #X), second - path to project (#P) + +rem Codepage 65001 or 866 breaks PVS +rem But codepage 20127 works + +chcp 20127 >NUL 2>NUL + +call .\scripts\check_project.bat +call .\scripts\CLMonitorDumpFilterLauncher_uVision.bat FILTER_AND_ANALYZE -keilPath %1 -projPath %2 -filterFile ".\PVS-STUDIO\filesToAnalyse.txt" +call .\scripts\view_pvs_log.bat %2 + diff --git a/scripts/_before_build_dump.bat b/scripts/_before_build_dump.bat new file mode 100644 index 0000000..1d58cad --- /dev/null +++ b/scripts/_before_build_dump.bat @@ -0,0 +1,6 @@ +@echo off +rem Expects three arguments, first - path to UV4.exe (can be obtained as #X), second - path to project (#P), third - current target name (quoted text) + +chcp 20127 >NUL || exit /b + +call .\scripts\CLMonitorDumpFilterLauncher_uVision.bat CREATE_AND_UPDATE_DUMP -keilPath %1 -projPath %2 -target %3 diff --git a/scripts/_before_compile.bat b/scripts/_before_compile.bat new file mode 100644 index 0000000..8db8856 --- /dev/null +++ b/scripts/_before_compile.bat @@ -0,0 +1,17 @@ +@echo off + +rem Expects two arguments, first - path to UV4.exe (can be obtained as #X), second - path to current file (#E) + +rem Codepage 65001 or 866 breaks PVS +rem But codepage 20127 works +chcp 20127 >NUL 2>NUL + +if not exist ".\PVS-STUDIO\" ( + echo "---------------------------" + echo "Please launch 'Before Build' script first (at least once); Go to Project->Options and enable it; change 'Target 1' to your target name" + echo "You can disable it after one full rebuild" + echo - + exit /B 1 +) + +call .\scripts\CLMonitorDumpFilterLauncher_uVision.bat ADD_COMPILED_FILE -keilPath %1 -filterFile ".\PVS-STUDIO\filesToAnalyse.txt" -file %2 \ No newline at end of file diff --git a/scripts/check_project.bat b/scripts/check_project.bat new file mode 100644 index 0000000..98440ad --- /dev/null +++ b/scripts/check_project.bat @@ -0,0 +1,21 @@ +@echo off +SET GIT_BASH_PATH=C:\Program Files\Git\bin\ + +REM enforce this codepage so cmd errors would be readable in keil +chcp 20127 >NUL 2>NUL + +REM I have to use .bat-file cause Keil can't directly call shell-script +REM if you have several bashes, please set env. variable GIT_BASH_PATH with a \ at the end +REM or, if you have one bash, you can add it in the PATH + +"%GIT_BASH_PATH%bash.exe" --login "%~dp0\check_project.sh" || goto :error + +goto :EOF + +:error + echo -------------------- + echo "Error has occured when running check_project.bat!" + echo "Please check environment variable GIT_BASH_PATH; it should contain path to bash with \ on the end" + echo -------------------- + exit /B 1 + diff --git a/scripts/check_project.sh b/scripts/check_project.sh new file mode 100644 index 0000000..ec3e4bd --- /dev/null +++ b/scripts/check_project.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# crude check if any file was added or removed from project +# search for changes in git diff that include tag +was_changed=$(git diff *.uvproj* | grep "[+,-]\s*" | sed -e 's###g') + +if [[ -n "$was_changed" ]]; then + echo "%%%%%%%%%%%%%%%%%%%%%%%%%%" + echo "%%%%%%%%%%%%%%%%%%%%%%%%%%" + echo "Warning when running PVS Studio:" + echo "%%%%%%%%%%%%%%%%%%%%%%%%%%" + echo "%%%%%%%%%%%%%%%%%%%%%%%%%%" + echo "--------------------------" + echo "Project file was changed! Some files were added or removed:" + echo "$was_changed" + echo "You may want to generate new dump-file for PVS-studio" + echo "For this:" + echo "1) Go to Project->Options->User, " + echo "2) Enable 'Before Compile C/C++ File' script and 'Before Build/Rebuild' script" + echo "3) Rebuild all" + echo "4) Disable those scripts once again" + echo "Please note, that this warning will go away only after you commited changes in project file!" + echo "--------------------------" + echo "%%%%%%%%%%%%%%%%%%%%%%%%%%" + echo "%%%%%%%%%%%%%%%%%%%%%%%%%%" +fi \ No newline at end of file diff --git a/scripts/ignore_warnings.pvsconfig b/scripts/ignore_warnings.pvsconfig new file mode 100644 index 0000000..cac7c1c --- /dev/null +++ b/scripts/ignore_warnings.pvsconfig @@ -0,0 +1,27 @@ +###### Common warnings + +# ignore 64-bit warnings +// -V::4 + +# allow C-style cast for primitive integer types (and void) +// -V:int:2005 +// -V:char:2005 +// -V:short:2005 +// -V:uint8_t:2005 +// -V:int8_t:2005 +// -V:uint16_t:2005 +// -V:int16_t:2005 +// -V:uint32_t:2005 +// -V:int32_t:2005 +// -V:uint64_t:2005 +// -V:int64_t:2005 +// -V:void:2005 + +# ignore 'The body of the statement should be enclosed in braces'; that doesn't look like a source of errors for us +// -V::2507 + +###### MISRA + +# ignore MISRA C++ 6-6-5 'A function should have a single point of exit at the end.' +# this goes againts our best practises and generally seems outdated +// -V::2506 \ No newline at end of file diff --git a/scripts/pvs_settings.xml b/scripts/pvs_settings.xml new file mode 100644 index 0000000..a819643 --- /dev/null +++ b/scripts/pvs_settings.xml @@ -0,0 +1,13 @@ + + + + true + + + \cmsis\ + \spl\ + \mcu_support_package\ + + + true + \ No newline at end of file diff --git a/scripts/view_pvs_log.bat b/scripts/view_pvs_log.bat new file mode 100644 index 0000000..916c048 --- /dev/null +++ b/scripts/view_pvs_log.bat @@ -0,0 +1,23 @@ +@echo off +SET PVS_STUDIO_PATH=C:\Program Files (x86)\PVS-Studio\ + +echo "##################### PVS Studio Analysis: #####################" + +rem Codepage 65001 or 866 breaks PVS +rem But codepage 20127 works + +chcp 20127 >NUL 2>NUL + +setlocal EnableDelayedExpansion + +SET PROJECT_DIR=%~dp1 +SET PROJECT_NAME=%~n1 + +SET FILTERED_DUMP="!PROJECT_DIR!PVS-STUDIO\!PROJECT_NAME!.FilteredCompilationDump.gz" +SET OUTPUT_LOG="!PROJECT_DIR!PVS-STUDIO\!PROJECT_NAME!.plog" +SET OUTPUT_LOG_PATH="!PROJECT_DIR!\PVS-STUDIO" + + +"%PVS_STUDIO_PATH%\CLMonitor.exe" analyzeFromDump -d !FILTERED_DUMP! -l !OUTPUT_LOG! -t "%~dp0\pvs_settings.xml" -c "%~dp0\ignore_warnings.pvsconfig" >NUL +"%PVS_STUDIO_PATH%\PlogConverter.exe" !OUTPUT_LOG! --renderTypes=Txt -o !OUTPUT_LOG_PATH! >NUL +more !OUTPUT_LOG_PATH!\!PROJECT_NAME!.plog.txt