Lecture 25: Core File and goto Makefiles, Networking Flashcards
core files
- when your program has an unrecoverable error, the operating system saves the heap/stack memory at the exact time of the failure into a file named “core”
- you can use the core file with the debugger
core dump file
- man 5 core
- unlimited -c unlimited
- second command enables it, which you may have to do
why is goto bad?
- prevents compiler from being able to make “nice” computer-science reductions of the program
- makes your code unreadable
- is really not necessary
why does C have a goto?
- because the compiler doesn’t have any more difficulty analyzing a program with gotos
- it is very useful and makes the program easier to read
what does goto look like?
- can define labels and goto those labels
int func(int x) {
int sum = 0;
again:
sum = sum + x’
if (x <= 0) {
goto get_out;
else
goto again;
get_out
return sum; }
how can goto make a program clearer to read
- when you really need to ditch the control flow of your program and take drastic measures
- ex. multiple for, while, if within each other, start_over: outside of it, goto start_over; on innermost if
when is goto useful?
- when it is necessary to break out of deeply nested loops (prev ex.)
- when you’re building a state machine in software
- should avoid goats unless there is a really good reason
makefile
- simple way to help organize code compilation
composed of rules: - target - usually a file to generate (can be an action like make clean)
- prerequisites - used to create the target
- recipe - action to carry out (must start with a tab)
example of hard coded makefile
hello: hello.c hellofunc.c
gcc -o hello hello.c hellofunc.c -l
OR
CC=gcc
CFlAGS=-l
hello: hello.o hellofunc.o
$(CC) -o hello hello.o hellofunc.o $(CFLAGS)
- can also add object files and header files
bubble sort
- lots of different ways with different performance/complexity
void bubble_simple(int *arr, int size) {
for (int k = 0; k < size; k++) {
for (int I = 1; I < size; I++) {
if (arr[I-1] > arr[i}) { // swap
arr[i-1]^ = arr[i];
arr[i] ^= arr[i-1];
arr[i-1]^ = arr[i];
}
}
bubble sort with better time complexity
void bubble(int *arr, int size) {
int swapped = 1;
while (swapped) {
swapped = 0;
for (int i = 1; I < size; I++) {
if (arr[I-1] > arr[i[) {
int tmp = arr[i-1];
arr[i-1] = arr[i];
arr[i] = tmp;
swapped = 1;
}
}
}
}
networking basics
- given a network and a set of systems, how do we actually send data between a subset of systems?
- first have to find systems (establish a route)
- decide how we’re going to communicate (protocol)
- establish a connection (socket)
internet protocol
- IP is an addressing an fragmentation protocol
- breaks communication into chunks (packets)
- routes packets from a source to a destination
- inherently unreliable (no guarantee anything will make it)
- different versions of it
IP Address
- each host or system has at least one IP address
- nnn.nnn.nnn.nnn (dotted decimal notation, 4 bytes, 32 bits)
- packets are sent from/to IP addresses (may traverse multiple routers
- public/private, NATs
Domain Name System
- DNS is a distributed system that resolves host names to IP addresses
- hierarchical, root servers, many authoritative servers
- name resolution can involve multiple queries, caching servers
- reverse lookup
transmission control protocol
- remember, IP is unreliable
- TCP builds on IP to create a reliable network connection (referred to as TCP/IP)
- supports acknowledgments and retransmission
- hosts identified by IP address and a port number
clients and servers
- a server is a process that waits for a connection
- a client is a process that connects to a server
- processes can be both!
- machines can have multiple servers and clients running at once
- once connected, clients and servers read and write data from/to each other much like a file
network sockets
- clients and servers communicate via sockets
- a socket is an endpoint for sending and receiving data
- a socket address consists of the IP address and port number (at least for TCP)
- port number is 16bits
- ports < 1-24 are privileged
server
- man 7 ip
- steps for listening
- create a socket()
- bind() that socket to an address and port
- listen() for a connection
- accept() the connection
- close() the connection
socket
- create an endpoint for communication
- int socket(int domain, int type, int protocol)
bind()
- assigning a name to a socket
- bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
- socket() gives us a fd
- bind() assigns an “address” to the socket
listen()
- marks the socket as a passive socket
- accepts incoming connections
- int listen(int sockfd, int backlog)
- backlog is the max length for the pending connections queue
- max # of waiting connections
accept()
- removes first connection request from pending connections queue
- must be called on a listen()ing socket
- add is filled with peer information
- creates a NEW connected socket
- this socket does not listen
- original socket is left alone
recv() and send()
- recv() is read() when flags = 0
- can behave differently depending on the flags
- send() is write() when flags = 0
- can behave differently depending on the flags