1 of 45

2 of 45

Who Am I?

Don’t care

Already know

3 of 45

Who Am I?

Don’t care

Already know

4 of 45

Who Are You?

Want to learn about

undefined behavior

Already know

5 of 45

Square

example

6 of 45

Confusing terminology

Not defined

Unspecified behavior

Implementation defined behavior

7 of 45

Undefined Behavior

behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements

C++ standard, defns.undefined

8 of 45

The compiler is free to assume

Undefined Behavior never

happens

9 of 45

Chekhov's Gun

(not my example, not example’s original name)

10 of 45

What are UBs good for?

11 of 45

12 of 45

“NULL pointer dereference crashes the program”

void crash_preventer(int signum) {

exit(1);

}

int main() {

signal(SIGSEGV, crash_preventer);

13 of 45

“NULL ptr deref raises a segmentation fault”

int main() {

void *ptr = mmap(� NULL,� 4096,� PROT_READ|PROT_WRITE,� MAP_ANONYMOUS|MAP_FIXED,� -1,� 0);

14 of 45

UBs are a necessary evil

15 of 45

UB’s “bad” behavior is a result of optimization

Not a rule, just an observation

16 of 45

17 of 45

Optimization steps

define i32 @some_func() {

create_frame

%1 = alloca i32, align 4

%2 = 42

store i32 %2, ptr %1

%3 = load i32, ptr %1

ret i32 %3

}

18 of 45

Optimization steps

define i32 @some_func() {

create_frame

%1 = alloca i32, align 4

%2 = 42

store i32 %2, ptr %1

ret i32 %2

}

19 of 45

Optimization steps

define i32 @some_func() {

create_frame

%1 = alloca i32, align 4

%2 = 42

ret i32 %2

}

20 of 45

Optimization steps

define i32 @some_func() {

create_frame

%1 = 42

ret i32 %1

}

21 of 45

Optimization steps

define i32 @some_func() {

%1 = 42

ret i32 %1

}

22 of 45

Peephole Optimization

A series of small code replacement, each retaining semantic meaning.

23 of 45

Breakdown of Chekhov's gun example

24 of 45

Null pointer dereference

doesn’t always look like

Null pointer dereference

25 of 45

Real Life Examples

Presented in a useless form

26 of 45

Example 1 - PLL initialization

  1. int some_calc(int param1, int param2) {
  2. int result = param1;
  3. while( result<CONTSTANT1 ) {
  4. result += CONSTANT2;
  5. result /= param2 - 1;
  6. }
  7. return result;
  8. }

27 of 45

Example 2 - hardware register

  1. void Gpio::set(int gpio, bool value) {
  2. uint64_t mmio_addr;
  3. uint32_t outval;
  4. assert(gpio >= 0);
  5. assert(gpio < 32);
  6. uint64_t gpio_bit = (1UL << gpio);
  7. if(value)
  8. m_gpio_outputs |= gpio_bit;
  9. else
  10. m_gpio_outputs &= ~gpio_bit;
  11. calcDataAddress(&mmio_addr, nullptr);
  12. mmio_write_32(mmio_addr, m_gpio_outputs);
  13. }

28 of 45

Signed Int Overflow

int func1(int);

int func2(int);

int func(int param) {

int sum = 0;

while(sum<5000) {

if( param<10 )

sum+=func1(param);

else

sum+=func2(param);

param++;

}

return sum;

}

29 of 45

Null Pointer Deref - Chekhov's gun example

secondfile.cpp:

#include <iostream>

extern void load_gun();

class Loader {

public:

Loader() {

std::cout<<"Loading gun\n";

load_gun();

}

};

static Loader loader;

30 of 45

31 of 45

32 of 45

33 of 45

UB scope expansion example

#define OFFSETOF(T,m)

static_cast<size_t>(

&reinterpret_cast<T*>(nullptr)->m

)

34 of 45

Using keywords restricts versatility

template<

typename T,

ListNode T::*offset>�class IntrusiveLinkedList {

35 of 45

At least we know which UBs there are… ??

  • No comprehensive list
  • “Not defined” = undefined
  • Sometimes, it does do what you expect

36 of 45

We can search the standard for “Undefined behavior”

37 of 45

Kinda

38 of 45

Searching for just “undefined” has false positives…

39 of 45

“Behavior is undefined” will find most

40 of 45

Even the standard sometimes can’t tell them apart

41 of 45

Some don’t have the word “undefined” at all

42 of 45

How can things be made better?

  • Language:
    • Remove UBs that are no longer needed
    • Remember that UBs are a huge problem for developers.
    • Don’t greedily extend the scope of UB
  • Compilers:
    • Error out on unconditional UB triggering!!!!!!!
    • UB sanitizer everywhere (I’m looking at you, Visual Studio).

43 of 45

UBs are a necessary evil

44 of 45

Slide #2 - Who am I?

45 of 45

Thank you