Week 4, 2020: Debugging Potluck
๐ Pre-Discussion Learning Material
๐ Topics
- C++ & Undefined behavior
- Matthew Andres Moreno
- Empirical debugging tools
- Charles Ofria
- Using gdb (command line basics & more through vscode)
- Emily Dolson
๐ Code Snippets
undefined behavior wonโt necessarily crash, until it does:
#include <iostream>
#include <vector>
int main() {
std::vector<char> vec(10, 'a');
std::vector<char> vec2(10000, 'z');
for (size_t i = 1; true; i*=10) {
std::cout << "index " << i << std::endl;
std::cout << "value " << vec[i] << std::endl;
}
}
undefined behavior can cause subtle bugs:
#include <iostream>
#include <array>
int main() {
std::array<char, 10> should_change{'a'};
const std::array<char, 10000> shouldnt{'z'};
std::cout << "shouldnt before " << shouldnt[0] << std::endl;
for (size_t i = 0; i < 50; ++i) {
should_change[i] = '!';
}
std::cout << "shouldnt after " << shouldnt[0] << std::endl;
}
(behavior changing based on optimization mode is a common calling card of UB)
undefined behavior can cause insidious bugs:
#include <iostream>
#include <vector>
int main() {
std::vector<char> should_change(10, 'a');
const std::vector<char> shouldnt(10000, 'z');
for (size_t i = 0; i < 50; ++i) {
should_change[i] = '!';
}
std::cout << ":( " << shouldnt[0] << std::endl;
}
optimizer assumes UB wonโt happen, adapted from cppreference:
#include <iostream>
#include <vector>
void bad_thing(bool flag) {
std::size_t val;
if (flag) val = 42;
std::cout << " flag: " << flag << std::endl;
std::cout << " val: " << val << std::endl;
}
int main() {
std::cout << "bad_thing(true)" << std::endl;
bad_thing(true);
std::cout << "bad_thing(false)" << std::endl;
bad_thing(false);
}