imported lab skeletons

This commit is contained in:
Sven Gestegard Robertz 2021-10-27 15:15:47 +02:00
parent 4fc8b6c771
commit e4df45f4a9
47 changed files with 15122 additions and 87 deletions

View file

@ -0,0 +1,81 @@
# An example CMakeLists.txt for the sanitizers example, showing how to
# enable sanitizers in a debug build.
# It uses generator expressions, to set additional flags when the build type
# is Debug.
#
# To try this out, first create a build directory for a release build,
# and do a release build, e.g.,
# % mkdir build-rel
# % cd build-rel
# % cmake SRC_DIR -DCMAKE_BUILD_TYPE=Release
# % make
#
# Run the examples and see that they crash.
#
# Then create another build directory and do a debug build:
#
# % mkdir build-dbg
# % cd build-dbg
# % cmake SRC_DIR -DCMAKE_BUILD_TYPE=Debug
# % make
#
# where SRC_DIR is the directory containing the source and CMakeLists.txt,
# e.g., .. if your build directories are placed in this directory.
#
# Run the examples and verify that the sanitizers find the errors.
#
# If you want to see the actual commands run during the build, for instance
# to verify that the correct compiler flags are used, you can do
#
# % make VERBOSE=1
cmake_minimum_required (VERSION 3.5)
project (Sanitizers)
set (CMAKE_CXX_STANDARD 11)
# The three standard build types are Release, Debug, and RelWithDebInfo.
# If set here, it forces that build type.
#
# set(CMAKE_BUILD_TYPE Release)
# set build type to DEBUG
# set(CMAKE_BUILD_TYPE Debug)
# or to get an optimized build w/ debug symbols
# set(CMAKE_BUILD_TYPE RelWithDebInfo)
# add the executables
add_executable(leak leak.cc)
add_executable(bounds bounds.cc)
add_executable(bounds-heap bounds-heap.cc)
add_executable(ub ub.cc)
add_executable(dangling dangling.cc)
add_executable(sum sum.cc)
add_executable(sum_alt sum.cc)
# set compiler flag to turn off optimization (for all builds)
# add_compile_options("-O0")
# or use generator expressions to set flags in debug builds
add_compile_options($<$<CONFIG:Debug>:-O0>)
# set compiler and linker flags to enable the relevant sanitizer
target_compile_options(leak PUBLIC $<$<CONFIG:Debug>:-fsanitize=leak>)
target_link_libraries(leak $<$<CONFIG:Debug>:-fsanitize=leak>)
target_compile_options(bounds PUBLIC $<$<CONFIG:Debug>:-fsanitize=address>)
target_link_libraries(bounds $<$<CONFIG:Debug>:-fsanitize=address>)
target_compile_options(bounds-heap PUBLIC $<$<CONFIG:Debug>:-fsanitize=address>)
target_link_libraries(bounds-heap $<$<CONFIG:Debug>:-fsanitize=address>)
target_compile_options(ub PUBLIC $<$<CONFIG:Debug>:-fsanitize=undefined>)
target_link_libraries(ub $<$<CONFIG:Debug>:-fsanitize=undefined>)
target_compile_options(dangling PUBLIC $<$<CONFIG:Debug>:-fsanitize=address>)
target_link_libraries(dangling $<$<CONFIG:Debug>:-fsanitize=address>)
target_compile_options(sum PUBLIC $<$<CONFIG:Debug>:-fsanitize=undefined>)
target_link_libraries(sum $<$<CONFIG:Debug>:-fsanitize=undefined>)
target_compile_options(sum_alt PUBLIC $<$<CONFIG:Debug>:-fsanitize=address>)
target_link_libraries(sum_alt $<$<CONFIG:Debug>:-fsanitize=address>)

View file

@ -0,0 +1,40 @@
# Define the compiler and the linker. The linker must be defined since
# the implicit rule for linking uses CC as the linker. g++ can be
# changed to clang++.
CXX = g++
CC = $(CXX)
# Define preprocessor, compiler, and linker flags. Uncomment the # lines
# if you use clang++ and wish to use libc++ instead of GNU's libstdc++.
# -g is for debugging.
CPPFLAGS = -std=c++11 -I.
CXXFLAGS = -O0 -Wall -Wextra -pedantic-errors -Wold-style-cast
CXXFLAGS += -std=c++11
CXXFLAGS += -g
LDFLAGS = -g
# CPPFLAGS += -stdlib=libc++
# CXXFLAGS += -stdlib=libc++
# LDFLAGS += -stdlib=libc++
PROGS=ub leak bounds bounds-heap dangling sum
ALL: $(PROGS)
leak: leak.cc
dangling: dangling.cc
bounds: bounds.cc
ub: ub.cc
sum: sum.cc
# Targets
# Phony targets
.PHONY: all clean test
# Standard clean
clean:
-rm $(PROGS)
-rm -r $(addsuffix .dSYM, $(PROGS))

View file

@ -0,0 +1,58 @@
# Define the compiler and the linker. The linker must be defined since
# the implicit rule for linking uses CC as the linker. g++ can be
# changed to clang++.
CXX = g++
CC = $(CXX)
# Define preprocessor, compiler, and linker flags. Uncomment the # lines
# if you use clang++ and wish to use libc++ instead of GNU's libstdc++.
# -g is for debugging.
CPPFLAGS = -std=c++11 -I.
CXXFLAGS = -O0 -Wall -Wextra -pedantic-errors -Wold-style-cast
CXXFLAGS += -std=c++11
CXXFLAGS += -g
LDFLAGS = -g
# CPPFLAGS += -stdlib=libc++
# CXXFLAGS += -stdlib=libc++
# LDFLAGS += -stdlib=libc++
PROGS=ub leak bounds bounds-heap dangling sum sum-alt bounds-alt bounds-heap-alt
ALL: $(PROGS)
leak: leak.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -fsanitize=leak -o $@ $<
dangling: dangling.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -fsanitize=address -o $@ $<
bounds: bounds.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -fsanitize=address -o $@ $<
bounds-heap: bounds-heap.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -fsanitize=address -o $@ $<
bounds-alt: bounds.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -fsanitize=undefined -o $@ $<
bounds-heap-alt: bounds-heap.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -fsanitize=undefined -o $@ $<
ub: ub.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -fsanitize=undefined -o $@ $<
sum: sum.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -fsanitize=undefined -o $@ $<
sum-alt: sum.cc
$(CXX) $(CPPFLAGS) $(CXXFLAGS) $(LDFLAGS) -fsanitize=address -o $@ $<
# Targets
# Phony targets
.PHONY: all clean
# Standard clean
clean:
-rm $(PROGS)
-rm -r $(addsuffix .dSYM, $(PROGS))

View file

@ -0,0 +1,64 @@
This directory contains a few small examples of how the google sanitizers
can be used to find problems related to memory management and undefined behaviour.
The sanitizers are libraries that are used to instrument your programs, which is
done by compiling and linking with the option -fsanitize=<SANITIZER>.
For building this example includes two makefiles, one for building without
sanitizers (Makefile) and one for building with them (Makefile.sanitizers).
Also included is a CMakeListst.txt which uses sanitizers when doing a debug build.
Examples:
The file leak.cc contains an example of a memory leak.
The files bounds.cc, bounds-heap.cc and sum.cc contain examples of accessing
outside the bounds of an array (on the stack and on the heap).
The file dangling.cc contains an example of using a dangling pointer.
The file ub.cc contains an example of undefined behaviour.
Demonstration:
First build the programs using Makefile, and run them.
Then, first do make clean and then build them using Makefile.sanitizers
(make -f Makefile.sanitizers)
Run the programs again, and see if the errors are detected. Try to understand
the diagnostics pringed when the sanitizer detects an error.
Note that the different sanitizers may produce different error messages
for the same problem. Compare the output from sum and sum_alt (which are
built from the same source file, but with different sanitizers.)
This example also includes a CMakeLists.txt that illustrates how to enable
the sanitizers for debug builds.
Building with cmake:
With cmake, make debug and release builds and compare, typically in
separate build directories:
For the release build:
% mkdir build-rel
% cd build-rel
% cmake -DCMAKE_BUILD_TYPE=Release SRC_DIR
% make
For the debug build:
% mkdir build-rel
% cd build-rel
% cmake -DCMAKE_BUILD_TYPE=Debug SRC_DIR
% make
Both gcc and clang use the google sanitizers, but different compiler versions
may use different versions of the sanitizers. If you have installed a more recent
compiler version, you may need to tell cmake to use that.
By default, cmake will use the system's default compiler. To specify which
compiler to use, you can add (for gcc)
-DCMAKE_CXX_COMPILER=g++
-DCMAKE_C_COMPILER=gcc
or, for clang:
-DCMAKE_CXX_COMPILER=clang++
-DCMAKE_C_COMPILER=clang

View file

@ -0,0 +1,25 @@
#include <iostream>
#include <numeric>
#include <memory>
using std::cout;
void print(int* a, int size)
{
for(int i=0; i < size; ++i){
cout << a[i] << " ";
}
cout << "\n";
}
void example()
{
std::unique_ptr<int[]> xs(new int[10]);
std::iota(xs.get(), xs.get()+10, 0);
print(xs.get(), 15);
}
int main()
{
example();
}

View file

@ -0,0 +1,24 @@
#include <iostream>
#include <numeric>
using std::cout;
void print(int* a, int size)
{
for(int i=0; i < size; ++i){
cout << a[i] << " ";
}
cout << "\n";
}
void example()
{
int xs[10];
std::iota(xs, xs+10, 0);
print(xs, 15);
}
int main()
{
example();
}

View file

@ -0,0 +1,37 @@
#include <iostream>
#include <numeric>
using std::cout;
struct Foo{
Foo(int s) :p(new int[s]), sz(s) {}
~Foo() {delete[] p;}
int* begin() {return p;}
int* end() {return begin()+sz;}
const int* begin() const {return p;}
const int* end() const {return begin()+sz;}
int* p;
int sz;
};
void print(Foo f)
{
for(const auto& x : f) cout << x << " ";
endl(cout);
}
void example1()
{
Foo f(10);
std::iota(std::begin(f), std::end(f), 0);
print(f);
cout << "after first print\n";
*f.begin()=123;
cout << "printing again\n";
print(f);
cout << "done\n";
}
int main()
{
example1();
}

View file

@ -0,0 +1,29 @@
#include <iostream>
using std::cout;
struct Foo{
Foo(int s) :p{new int[s]} {}
int* p;
};
struct Bar{
Bar(int x) :f(x) {}
Foo f;
};
void example1()
{
Foo f(10);
{
cout << "entering inner block\n";
Bar b(20);
cout << "leaving inner block\n";
}
cout << "leaving example1\n";
}
int main()
{
example1();
cout << "leaving main\n";
}

View file

@ -0,0 +1,20 @@
#include <iostream>
#define N (4)
int x = 1000;
int a[]{ 1, 2, 3, 4 };
int y = 2000;
int main()
{
int sum{0};
std::cout << "welcome to the buggy sum program. the sum should be 10\n";
for (int i = 0; i <= N; i++)
sum += a[i];
std::cout << "sum = " << sum << "\n";
return 0;
}

31
lab1/buggy_programs/ub.cc Normal file
View file

@ -0,0 +1,31 @@
#include <iostream>
#include <vector>
#include <cassert>
#include <numeric>
using std::cout;
using std::endl;
std::vector<int> create_vector(int s)
{
assert(s >= 0);
std::vector<int> res(s);
}
template <typename C>
void print_seq(const C& c)
{
for(const auto& x : c) cout << x << " ";
cout << "\n";
}
void example()
{
auto v = create_vector(10);
std::iota(begin(v), end(v), 0);
print_seq(v);
}
int main()
{
example();
}