profile, gprof, sanitize

This commit is contained in:
timerix 2023-03-15 18:01:03 +06:00
parent 9f04507bd8
commit ec4209831b
6 changed files with 109 additions and 56 deletions

View File

@ -1,18 +1,22 @@
# v6
+ `build_profile` task was split to `profile` and `gprof`
+ added task `sanitize`
# v5 # v5
+ added task clean + added task `clean`
+ added task exec_dbg + added task `exec_dbg`
+ added task build_profile + added task `build_profile`
+ added -flto optimization to build_exec task + added `-flto` optimization to `build_exec` task
+ added -fprofile-use to build_exec task + added `-fprofile-use` to `build_exec` task
+ removed default configs loading in `init.sh`, now reads just line with version from `cbuild/default.config` and `default.config` + removed default configs loading in `init.sh`, now reads just line with version from `cbuild/default.config` and `default.config`
+ OBJDIR structure changed + `OBJDIR` structure changed
+ added error on unknown task in config + added error on unknown task in config
+ makefile now writes logs to make_raw.log + makefile now writes logs to `make_raw.log`
+ added makefile task fix_log + added makefile task `fix_log`
+ new comments in scripts and Makefile + new comments in scripts and Makefile
+ wrapped arguments with quots in scripts + wrapped arguments with quots in scripts
+ now u should add CPP_ARGS to LINKER_ARGS manually + now you have to add `CPP_ARGS` to `LINKER_ARGS` manually
+ added error(msg) function to functions.sh + added `error(msg)` function to `functions.sh`
+ replaced printf calls with myprint in scripts + replaced `printf` calls with `myprint` in scripts
+ added default .gitignore + added default `.gitignore`
+ added *.log to .gitignore + added *.log to `.gitignore`

View File

@ -4,12 +4,8 @@
all: build_exec_dbg all: build_exec_dbg
# generates different profile info # creates executable using profiling info generated by profile
build_profile: build_exec: profile
@cbuild/call_task.sh build_profile 2>&1 | tee make_raw.log
# creates executable using profile info generated by build_profile
build_exec: build_profile
@cbuild/call_task.sh build_exec 2>&1 | tee -a make_raw.log @cbuild/call_task.sh build_exec 2>&1 | tee -a make_raw.log
# creates executable with debug info and no optimizations # creates executable with debug info and no optimizations
@ -48,6 +44,19 @@ exec_dbg: build_exec_dbg
valgrind: build_exec_dbg valgrind: build_exec_dbg
@cbuild/call_task.sh valgrind 2>&1 | tee -a make_raw.log @cbuild/call_task.sh valgrind 2>&1 | tee -a make_raw.log
# generates profiling info
profile:
@cbuild/call_task.sh profile 2>&1 | tee make_raw.log
# compiles program with -pg and runs it with gprof
# uses gprof2dot python script to generate function call tree
gprof:
@cbuild/call_task.sh gprof 2>&1 | tee make_raw.log
# compiles executable with sanitizers and executes it to find errors and warnings
sanitize:
@cbuild/call_task.sh sanitize 2>&1 | tee make_raw.log
###################################### ######################################
###### Other tasks ####### ###### Other tasks #######
###################################### ######################################

View File

@ -1,18 +1,18 @@
#!/bin/bash #!/bin/bash
CBUILD_VERSION=5 CBUILD_VERSION=6
CONFIG_VERSION=1 CONFIG_VERSION=1
PROJECT="NULL" PROJECT="NULL"
CMP_C=gcc CMP_C="gcc"
CMP_CPP=g++ CMP_CPP="g++"
STD_C=c11 STD_C="c11"
STD_CPP=c++17 STD_CPP="c++11"
WARN_C="-Wall -Wno-discarded-qualifiers" WARN_C="-Wall -Wno-discarded-qualifiers -Wextra -Wno-unused-parameter"
WARN_CPP="-Wall" WARN_CPP="-Wall -Wextra -Wno-unused-parameter"
SRC_C="$( find src -name '*.c')" SRC_C="$( find src -name '*.c')"
SRC_CPP="$( find src -name '*.cpp')" SRC_CPP="$( find src -name '*.cpp')"
#TESTS_C="$( find tests -name '*.c')" TESTS_C="$( find tests -name '*.c')"
#TESTS_CPP="$(find tests -name '*.cpp')" TESTS_CPP="$(find tests -name '*.cpp')"
# OBJDIR structure: # OBJDIR structure:
# ├── objects - dir where compiled *.o files are stored. cleans every call of build task # ├── objects - dir where compiled *.o files are stored. cleans every call of build task
@ -40,26 +40,13 @@ esac
# TASKS # TASKS
case "$TASK" in case "$TASK" in
# generates different profile info # creates executable using profiling info if it exists
build_profile)
OUTDIR="$OUTDIR/profile"
# -flto applies more optimizations across object files
# -flto=auto is needed to multithreaded copilation
# -fuse-linker-plugin is required to use static libs with lto, it strips away all
# -pg adds code to executable, that generates file containing function call info (gmon.out)
# -fprofile-generate
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -pg -fprofile-generate -fprofile-prefix-path=$(realpath $OBJDIR)/objects"
CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS"
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
TASK_SCRIPT=cbuild/default_tasks/profile.sh
POST_TASK_SCRIPT=
;;
# creates executable using profile info generated by build_profile
build_exec) build_exec)
# -flto applies more optimizations across object files # -flto applies more optimizations across object files
# -flto=auto is needed to multithreaded copilation # -flto=auto is needed to multithreaded copilation
# -fuse-linker-plugin is required to use static libs with lto, it strips away all # -fuse-linker-plugin is required to use static libs with lto
# -fprofile-use enables compiler to use profiling info files to optimize executable
# -fprofile-prefix-path sets path where profiling info about objects are be saved
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-use -fprofile-prefix-path=$(realpath $OBJDIR)/objects" C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-use -fprofile-prefix-path=$(realpath $OBJDIR)/objects"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS" LINKER_ARGS="$CPP_ARGS"
@ -69,7 +56,7 @@ case "$TASK" in
;; ;;
# creates executable with debug info and no optimizations # creates executable with debug info and no optimizations
build_exec_dbg) build_exec_dbg)
C_ARGS="-O0 -g" C_ARGS="-O0 -g3"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS" LINKER_ARGS="$CPP_ARGS"
PRE_TASK_SCRIPT= PRE_TASK_SCRIPT=
@ -87,7 +74,7 @@ case "$TASK" in
;; ;;
# creates shared library with debug symbols and no optimizations # creates shared library with debug symbols and no optimizations
build_shared_lib_dbg) build_shared_lib_dbg)
C_ARGS="-O0 -g -fpic -shared" C_ARGS="-O0 -g3 -fpic -shared"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS -Wl,-soname,$SHARED_LIB_FILE" LINKER_ARGS="$CPP_ARGS -Wl,-soname,$SHARED_LIB_FILE"
PRE_TASK_SCRIPT= PRE_TASK_SCRIPT=
@ -104,7 +91,7 @@ case "$TASK" in
;; ;;
# creates static library with debug symbols and no optimizations # creates static library with debug symbols and no optimizations
build_static_lib_dbg) build_static_lib_dbg)
C_ARGS="-O0 -g" C_ARGS="-O0 -g3"
CPP_ARGS="$C_ARGS" CPP_ARGS="$C_ARGS"
PRE_TASK_SCRIPT= PRE_TASK_SCRIPT=
TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh TASK_SCRIPT=cbuild/default_tasks/build_static_lib.sh
@ -119,6 +106,45 @@ case "$TASK" in
VALGRIND_ARGS="-s --log-file=valgrind.log --read-var-info=yes --track-origins=yes --fullpath-after=$PROJECT/ --leak-check=full --show-leak-kinds=all" VALGRIND_ARGS="-s --log-file=valgrind.log --read-var-info=yes --track-origins=yes --fullpath-after=$PROJECT/ --leak-check=full --show-leak-kinds=all"
TASK_SCRIPT=cbuild/default_tasks/valgrind.sh TASK_SCRIPT=cbuild/default_tasks/valgrind.sh
;; ;;
# generates profiling info
profile)
OUTDIR="$OUTDIR/profile"
# -flto applies more optimizations across object files
# -flto=auto is needed to multithreaded copilation
# -fuse-linker-plugin is required to use static libs with lto
# -pg adds code to executable, that generates file containing function call info (gmon.out)
# -fprofile-generate generates executable with profiling code
# -fprofile-prefix-path sets path where profiling info about objects will be saved
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -fprofile-generate -fprofile-prefix-path=$(realpath $OBJDIR)/objects"
CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS"
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
TASK_SCRIPT=cbuild/default_tasks/profile.sh
POST_TASK_SCRIPT=
;;
# compiles program with -pg and runs it with gprof
# uses gprof2dot python script to generate function call tree (pip install gprof2dot)
# requires graphviz (https://www.graphviz.org/download/source/)
gprof)
OUTDIR="$OUTDIR/gprof"
# -pg adds code to executable, that generates file containing function call info (gmon.out)
C_ARGS="-O2 -flto=auto -fuse-linker-plugin -pg"
CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS"
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
TASK_SCRIPT=cbuild/default_tasks/gprof.sh
POST_TASK_SCRIPT=
;;
# compiles executable with sanitizers and executes it to find errors and warnings
sanitize)
OUTDIR="bin/sanitize"
C_ARGS="-O0 -g3 -fsanitize=undefined,address"
CPP_ARGS="$C_ARGS"
LINKER_ARGS="$CPP_ARGS"
PRE_TASK_SCRIPT=cbuild/default_tasks/build_exec.sh
TASK_SCRIPT=cbuild/default_tasks/exec.sh
POST_TASK_SCRIPT=
;;
# deletes generated files # deletes generated files
clean) clean)
TASK_SCRIPT=cbuild/default_tasks/clean.sh TASK_SCRIPT=cbuild/default_tasks/clean.sh

View File

@ -8,6 +8,7 @@ prof_files=$(find "$OBJDIR/profile/" -name '*.gcda')
if [ -z "$prof_files" ]; then if [ -z "$prof_files" ]; then
myprint "${YELLOW}no profiling info found" myprint "${YELLOW}no profiling info found"
else else
myprint "${GREEN}profiling info found"
for prof_file in $prof_files; do for prof_file in $prof_files; do
myprint "${GRAY}$(basename $prof_file)" myprint "${GRAY}$(basename $prof_file)"
cp $prof_file "$OBJDIR/objects/" cp $prof_file "$OBJDIR/objects/"

20
default_tasks/gprof.sh Normal file
View File

@ -0,0 +1,20 @@
#!/bin/bash
cd "$OUTDIR"
# deleting all files except excutable
echo "$(find . ! -name $EXEC_FILE -type f -delete)"
# executing file compiled with -pg
myprint "${BLUE}executing $OUTDIR/$EXEC_FILE"
./$EXEC_FILE > exec.log
myprint "${GREEN}execution log saved to ${CYAN}$OUTDIR/exec.log"
# generating function call graph
myprint "${BLUE}generating function call graph..."
gprof ./$EXEC_FILE > gprof.log
gprof2dot gprof.log > gprof2dot.graph
dot gprof2dot.graph -Tpng -Gdpi=300 -o gprof2dot.png
myprint "${GREEN}function call graph saved to ${CYAN}$OUTDIR/gprof2dot.png"
cd ../..

View File

@ -5,7 +5,7 @@ cd "$OUTDIR"
# deleting all files except excutable # deleting all files except excutable
echo "$(find . ! -name $EXEC_FILE -type f -delete)" echo "$(find . ! -name $EXEC_FILE -type f -delete)"
# executing file compiled with -pg and -fprofile-gen # executing file compiled with -fprofile-gen
myprint "${BLUE}executing $OUTDIR/$EXEC_FILE" myprint "${BLUE}executing $OUTDIR/$EXEC_FILE"
./$EXEC_FILE > exec.log ./$EXEC_FILE > exec.log
myprint "${GREEN}execution log saved to ${CYAN}$OUTDIR/exec.log" myprint "${GREEN}execution log saved to ${CYAN}$OUTDIR/exec.log"
@ -15,11 +15,4 @@ clean_dir ../../$OBJDIR/profile
mv ../../$OBJDIR/objects/*.gcda ../../$OBJDIR/profile/ mv ../../$OBJDIR/objects/*.gcda ../../$OBJDIR/profile/
myprint "${GREEN}$(ls ../../$OBJDIR/profile | wc -l) *.gcda profiling files have written to $OBJDIR/profile" myprint "${GREEN}$(ls ../../$OBJDIR/profile | wc -l) *.gcda profiling files have written to $OBJDIR/profile"
# generating function call graph
myprint "${BLUE}generating function call graph..."
gprof ./$EXEC_FILE > gprof.log
gprof2dot gprof.log > gprof2dot.graph
dot gprof2dot.graph -Tpng -Gdpi=300 -o gprof2dot.png
myprint "${GREEN}function call graph saved to ${CYAN}$OUTDIR/gprof2dot.png"
cd ../.. cd ../..