Skip to content
Snippets Groups Projects
Commit 243c4054 authored by Matteo Cicuttin's avatar Matteo Cicuttin
Browse files

INFO0939-2021 code.

parent 12fcb49e
No related branches found
No related tags found
No related merge requests found
Prerequisites for the class:
---
* Having access to a Unix machine
* Having access to the compiler (`gcc` or `clang`), the debugger (`gdb`) and `wget`
* Having access to the compiler (`gcc` or `clang`), the debugger (`gdb`), Valgrind and `wget`
* NIC5 satisfies all the requirements
Instructions for downloading the example code
---
The git repository is located at [here](https://gitlab.onelab.info/mcicuttin/snippets/INFO0939) (`https://gitlab.onelab.info/mcicuttin/snippets/INFO0939`). We will use the following files:
The git repository is located at [here](https://gitlab.onelab.info/mcicuttin/snippets/info0939) (`https://gitlab.onelab.info/mcicuttin/snippets/info0939`). We will use the following files:
- `intdiv.c` for the `assert()` example on the integer division program
- `stack_corrupt.c` for a debugging exercise
- `cache.c` for a profiling exercise
......@@ -15,7 +15,7 @@ You can download the files on your machine or on NIC5 via `wget`:
```
# This command is needed only when you open a new shell
export REPO_BASE=https://gitlab.onelab.info/mcicuttin/snippets/INFO0939/-/raw/master/
export REPO_BASE=https://gitlab.onelab.info/mcicuttin/snippets/-/raw/master/info0939
# Files are then donwloaded as following:
wget $REPO_BASE/intdiv.c
......@@ -36,7 +36,7 @@ To debug with GDB: `gdb <progname>`, then
* `break <file:line>`: set a breakpoint
* `p`: print the value of a variable
Integer division program & `assert()`
Example: Integer division & `assert()`
---
You are not really required to run this code, but...
......@@ -44,12 +44,36 @@ You are not really required to run this code, but...
* Compile with `gcc -O3 -DNDEBUG -o intdiv intdiv.c` (release mode)
* Try to pass a negative integer to the function, compile the program in both modes and see what happens
Debugging exercise with `stack_corrupt.c`
Debugging example `selectionsort.c`
---
Examples of stepping, breakpointing & inspecting values with GDB
* Compile with `gcc -g -o selectionsort selectionsort.c`
Debugging example `backtrace.c`
---
Example of using the `backtrace` command in GDB
* Compile with `gcc -g -o backtrace backtrace.c`
Debugging exercise: `insertionsort.c`
---
* Compile with `gcc -g -o insertionsort insertionsort.c`
* Run with `./insertionsort`. What do you see?
* Launch the code in GDB find why it crashes
Debugging exercise: `stack_corrupt.c`
---
* Compile with `gcc -g -o stack_corrupt stack_corrupt.c`
* Run with `./stack_corrupt`. What do you see?
* Launch the code in GDB and try to explain what you see
Profiling exercise with `cache.c`
Profiling example with `cache.c`
---
Example usage of cachegrind to find cache-unfriendly code
* Compile with `gcc -O3 -g -o cache cache.c`
* Run with `valgrind --tool=cachegrind ./cache`
\ No newline at end of file
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#define ARRAY_LEN 10
#define VALUE_MAX 100
static void
sum(int *r, const int *a, const int *b, size_t N)
{
for (size_t i = 0; i < N; i++)
r[i] = a[i] + b[i];
}
static void
f(int *r , const int *a, const int *b, size_t N)
{
return sum(r,a,b,N);
}
static void
g(int *r, const int *a, const int *b, size_t N)
{
return sum(r,a,b,N-200);
}
int main(void)
{
srand(time(NULL));
int *a = (int *) malloc(ARRAY_LEN * sizeof(int));
int *b = (int *) malloc(ARRAY_LEN * sizeof(int));
int *r = (int *) malloc(ARRAY_LEN * sizeof(int));
if (!a || !b || !r)
{
printf("malloc() failed\n");
return 1;
}
for (size_t i = 0; i < ARRAY_LEN; i++)
{
a[i] = rand() % VALUE_MAX;
b[i] = rand() % VALUE_MAX;
}
f(r, a, b, ARRAY_LEN);
g(r, a, b, ARRAY_LEN);
free(a);
free(b);
free(r);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <stdint.h>
#define ARRAY_LEN 8
#define VALUE_MAX 100
static void
insertionsort(int *a, size_t N)
{
uint32_t j = 0;
while (j < N)
{
int key = a[j];
uint32_t i = j - 1;
while (i >= 0 && a[i] > key)
{
printf("%lu %lu\n", j, i);
a[i+1] = a[i];
i = i-1;
}
a[i+1] = key;
j = j+1;
}
}
static void
print_array(const int *a, size_t N)
{
for (size_t i = 0; i < N; i++)
printf("%d ", a[i]);
printf("\n");
}
int main(void)
{
srand(time(NULL));
int a[ARRAY_LEN];
for (size_t i = 0; i < ARRAY_LEN; i++)
a[i] = rand() % VALUE_MAX;
print_array(a, ARRAY_LEN);
insertionsort(a, ARRAY_LEN);
print_array(a, ARRAY_LEN);
return 0;
}
......@@ -21,26 +21,35 @@ integer_division(int x, int y, struct div_result *res)
/* The loop invariant is that
* - quotient * y + res has to be equal to x
* - y > 0
* The invariant must be true before, during and after the loop.
* The invariant must be true before and after the loop, and
* at the end of its body.
*/
assert( (res.quo*y + res.rem == x) && res.rem >= 0 && y > 0 );
assert( (res->quo*y + res->rem == x) && res->rem >= 0 && y > 0 );
while (res.rem >= y)
while (res->rem >= y)
{
/* At this point invariant AND while condition should be valid */
assert( (res.quo*y + res.rem == x) && res.rem >= 0 && y > 0 && res.rem >= y );
assert( (res->quo*y + res->rem == x) && res->rem >= 0 && y > 0 && res->rem >= y );
res.rem = res.rem - y;
res.quo = res.quo + 1;
res->rem = res->rem - y;
res->quo = res->quo + 1;
/* At this point the invariant should be re-established */
assert( (res.quo*y + res.rem == x) && res.rem >= 0 && y > 0 );
assert( (res->quo*y + res->rem == x) && res->rem >= 0 && y > 0 );
}
/* Postcondition: invariant AND NOT while condition */
assert( (res.quo*y + res.rem == x) && res.rem >= 0 && y > 0 && rem < y );
assert( (res->quo*y + res->rem == x) && res->rem >= 0 && y > 0 && res->rem < y );
/* In addition, note that IF we enter the cycle THEN res.rem ALWAYS
* decreases. res.rem is a ``bound function'' and allows you to say
* that your program ALWAYS terminates. */
}
int main(void)
{
struct div_result res;
integer_division(10, 4, &res);
printf("%d %d\n", res.quo, res.rem);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#define ARRAY_LEN 8
#define VALUE_MAX 100
static void
selectionsort(int *a, size_t N)
{
assert(N > 0);
for (size_t i = 0; i < N-1; i++)
{
size_t min_pos = i;
for (size_t j = 0; j < N; j++)
if (a[j] < a[min_pos])
min_pos = j;
if (min_pos != i)
{
int tmp = a[i];
a[i] = a[min_pos];
a[min_pos] = tmp;
}
}
}
static void
print_array(const int *a, size_t N)
{
for (size_t i = 0; i < N; i++)
printf("%d ", a[i]);
printf("\n");
}
int main(void)
{
srand(time(NULL));
int a[ARRAY_LEN];
for (size_t i = 0; i < ARRAY_LEN; i++)
a[i] = rand() % VALUE_MAX;
print_array(a, ARRAY_LEN);
selectionsort(a, ARRAY_LEN);
print_array(a, ARRAY_LEN);
return 0;
}
......@@ -2,7 +2,7 @@
#include <stdlib.h>
#include <string.h>
#define BUFSZ 4
#define BUFSZ (0x42 >> 4)
struct mystruct
{
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment