---
tags: jserv-Linux
---
# 2021q1 Homework1 (lab0)
contributed by < `asef18766` >
## env
* ubuntu 20.04 64bit on Vmware
```shell
$ uname -a
Linux ubuntu 5.8.0-43-generic #49~20.04.1-Ubuntu SMP Fri Feb 5 09:57:56 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
```
## basic queue features
- [x] new
- [x] free
- [x] insert_head
- [x] insert_tail
- [x] remove_head
- [x] size
- [x] reverse
- [x] sort
### structure
```c=
typedef struct {
list_ele_t *head; /* Linked list of elements */
list_ele_t *tail; /* Last element of linked list */
u_int32_t count; /* current element count of queue */
} queue_t;
```
### new/free
* new: nothing special
* free: need to add a check for null pointer input. otherwise, iterate through all the elements in the list and free them
### insert_head / insert_tail
1. check if queue pointer is NULL
2. `malloc` a new element and check if it's NULL
3. copy string and link elements
### remove_head
1. check if queue is not null and with first element existed
2. if `sp` is not null, copy the value of removed element into it
3. remove element and relink
### size
1. check if queue pointer is null
2. return `count`
### reverse
1. check if queue pointer is null
2. make each element points to previous element
3. swap head and tail pointer
4. make tail object points to NULL
### sort
* just a merge sort
## ASan debugging
1. enable ASan by ```make SANITIZER=1```
2. use ```make test``` to run through all the testcases
3. from log we can know that there is a global BOF happend
```c=132
/* Add a new parameter */
void add_param(char *name,
int *valp,
char *documentation,
setter_function setter)
{
param_ptr next_param = param_list;
param_ptr *last_loc = ¶m_list;
while (next_param && strcmp(name, next_param->name) > 0) {
last_loc = &next_param->next;
next_param = next_param->next;
}
param_ptr ele = (param_ptr) malloc_or_fail(sizeof(param_ele), "add_param");
ele->name = name;
ele->valp = valp; /* error here */
ele->documentation = documentation;
ele->setter = setter;
ele->next = next_param;
*last_loc = ele;
}
```
4. according to the log, the BOF happend with variable ```param_list```. Use GDB to set a hardware watchpoint by ```watch param_list```
```c=132
/* Add a new parameter */
void add_param(char *name,
int *valp,
char *documentation,
setter_function setter)
{
param_ptr next_param = param_list;
param_ptr *last_loc = ¶m_list;
while (next_param && strcmp(name, next_param->name) > 0) {
last_loc = &next_param->next;
next_param = next_param->next;
}
param_ptr ele = (param_ptr) malloc_or_fail(sizeof(param_ele), "add_param");
ele->name = name;
ele->valp = valp;
ele->documentation = documentation;
ele->setter = setter;
ele->next = next_param;
*last_loc = ele; // write happend here
}
```
5. after a few step, we can observe that there are some vulnerable force casts
```c=104
add_param("simulation", (int*)&simulation, "Start/Stop simulation mode", NULL);
add_param("verbose", &verblevel, "Verbosity level", NULL);
add_param("error", &err_limit, "Number of errors until exit", NULL);
add_param("echo", (int*)&echo, "Do/don't echo commands", NULL);
```
6. patch them to the correct type
```c
int simulation = false;
...
static int echo = 0;
```
## valgrind debugging
* in ```linenoise.c```, the global objects ```history``` was not remove until it triggers ```atexit```
* however, the code wasn't register it
* manual free whenever the program finished
```c=788
ok = ok && run_console(infile_name);
ok = ok && finish_cmd();
linenoiseAtExit();
```
## dudect
### Student’s t-distribution
* usage: to check whether samples is close to population
* input: samples, population mean,population varience
* output: confidence interval (is the data close to population)
### improvement
* [cpucycle](https://www.itread01.com/p/149683.html)
```c=
#include <stdint.h>
#include <time.h>
static inline int64_t cpucycles(void)
{
/*
* use this method to avoid time sampling error
*/
struct timespec t;
clock_gettime(CLOCK_MONOTONIC, &t);
return t.tv_nsec;
}
```