15-213 RECITATION CACHE LAB AND C Aishwarya Prem Renu 16 Feb 2015

advertisement
15-213 RECITATION
CACHE LAB AND C
Aishwarya Prem Renu
16 Feb 2015
Agenda
o Buffer lab – Due TOMORROW!
o Cache lab – Out TOMORROW! Due 26th Feb
o C Assessment
o Using the C Standard Library
o Compilation (gcc and make)
o Debugging Tips (Yes, you can still use GDB. )
o Version Control
o Style
o Demo
C Assessment
o Cache Lab = First ‘Programming in C’ Lab
o Steps to see if you’re ready:
o Can you solve all of these upcoming C-exercises effortlessly?
o These problems test fundamental C-concepts.
o If not, please come to the C-bootcamp
o DATE, TIME, LOCATION: TBA
o You need this for the rest of the course. So, if in doubt, COME TO
THE BOOTCAMP, and get all your doubts cleared!
Important C Topics
o
o
o
o
Types: Pointers/Structs
Memory Management: Malloc/Free, Valgrind
Common library functions: string.h, stdlib.h, stdio.h
Grab-bag: macros, typedefs, function-pointers,
header-guards
Exercise #1
Spot the errors!
int main()
{
int* a = malloc(100*sizeof(int));
for (int i=0; i<100; i++)
{
if (a[i] == 0) a[i]=i;
else a[i]=0;
}
free(a);
return 0;
}
Exercise #1
int main()
{
int* a = malloc(100*sizeof(int));
/* Q.3 Is anything missing here? */
for (int i=0; i<100; i++)
{
if (a[i] == 0) a[i]=i;
else a[i]=0;
}
int b = sizeof(a);
int c = (a == &a[0]);
free(a);
return 0;
}
Malloc does not
initialize memory! So
you get junk data,
and the behavior of
main is undefined.
Q.1 What can you
use instead of
malloc, so you can be
sure of the contents?
Q.2 What are the values
of b and c?
Q.4 What does
free(a) do?
Exercise #1
int main()
{
int* a = malloc(100*sizeof(int));
if(a == NULL) {
callerror(); //Define your own function
return;
}
for (int i=0; i<100; i++)
{
if (a[i] == 0) a[i]=i;
else a[i]=0;
}
free(a);
int b = sizeof(a);
// b = 8 (for
int c = (a == &a[0]);
// c = 1
return 0;
}
Malloc may return
NULL!
In that case, you would
get a dreaded
Segmentation fault
when you try to
dereference.
And Nope, you do not
want that happening.
64-bit systems)
Exercise #2
#define SUM(a,b) a+b
int sum(int a, int b)
{
return a+b;
}
int main
{
int c = SUM(2,3)*4;
int d = sum(2,3)*4;
return 1;
}
Q.1 What are the values of c and d?
Exercise #3
Safe or not?
int * funfun(int * allocate)
{
allocate = malloc(sizeof(int));
int a = 3;
return &a;
}
int main
{
int * ptr1;
int * ptr2 = funfun(ptr1);
printf(“%p %p”, ptr1, ptr2);
return 1;
}
Exercise #3
Safe or not?
int * funfun(int * allocate)
{
allocate = malloc(sizeof(int));
int a = 3;
return &a;
}
int main
{
int * ptr1;
int * ptr2 = funfun(ptr1);
printf(“%p %p”, ptr1, ptr2);
return 1;
}
Function returning
address of local variable!
Not allowed that was
allocated on the stack
and is not safe to access
after you return from
funfun!
Note: Printing pointer
values
Exercise #4
Spot the errors!
struct node
{
int a;
struct node* next;
};
typedef struct node * nodeptr;
int main()
{
nodeptr ** data = (nodeptr **)malloc(4*sizeof(nodeptr *));
for( int i = 0; i<4; i++)
{
data[i] = (nodeptr *)malloc(3*sizeof(nodeptr));
}
for( int j = 0; j<3; j++)
{
data[0][j]->a = 213;
}
}
Exercise #4
struct node
{
int a;
struct node* next;
};
typedef struct node * nodeptr;
has been allocated to be of type nodeptr *,
However, each of these nodeptr in the heap do not
point to anything yet, and are uninitialized! Hence,
when you dereference data[0][j], you get a
Segmentation Fault.
data[i]
int main()
{
nodeptr ** data = (nodeptr **)malloc(4*sizeof(nodeptr *));
for( int i = 0; i<4; i++)
{
data[i] = (nodeptr *)malloc(3*sizeof(nodeptr));
}
for( int j = 0; j<3; j++)
{
data[0][j] = malloc(sizeof(struct node));
data[0][j]->a = 213;
}
Q. Now, are all accesses safe?
/* Free everything you malloc! */
}
Exercise #4
struct node
{
int a;
struct node* next;
};
typedef struct node * nodeptr;
has been allocated to be of type nodeptr *,
However, each of these nodeptr in the heap do not
point to anything yet, and are uninitialized! Hence,
when you dereference data[0][j], you get a
Segmentation Fault.
data[i]
NO! Check if what malloc returned is nonNULL before you dereference!
int main()
{
nodeptr ** data = (nodeptr **)malloc(4*sizeof(nodeptr *));
for( int i = 0; i<4; i++)
{
data[i] = (nodeptr *)malloc(3*sizeof(nodeptr));
}
for( int j = 0; j<3; j++)
{
data[0][j] = malloc(sizeof(struct node));
data[0][j]->a = 213;
}
/* Free everything you malloc! */
}
Use the C Standard Library
o Please Use it!
o Don’t write code that’s already been written!
o Your work might have a bug or lack features
o You spend time writing code that may be inefficient compared to an existing solution.
o All C Standard Library functions are documented.
o Some of the commonly used ones are:
o stdlib.h: malloc, calloc, free, exit, atoi, abs, etc
o string.h: strlen, strcpy, strcmp, strstr, memcpy, memset, etc
o stdio.h: printf, scanf, sscanf, etc
o Use the UNIX man command to look up usage / online references.
Example: getopt
int main(int argc, char** argv)
o getopt is used to break up (parse) options
{
in command lines for easy parsing by shell
int opt, x;
procedures, and to check for legal options.
/* looping over arguments */
(From the man pages! See, it’s really helpful!)
while(-1 != (opt = getopt(argc, argv, “x:")))
{
o Use it to parse command line arguments and
switch(opt)
don’t write your own parser!
{
case 'x':
o Colon in “x:” indicates that it is a required
x = atoi(optarg);
argument
break;
default:
o optarg is set to value of option argument
printf(“wrong argument\n");
break;
o Returns -1 when no more args are present
}
}
o Useful for Cache lab!
}
Write Robust Code
We are writing code for the real world: errors will happen!
o System calls may fail
o User may enter invalid arguments
o Connections may die --- Experience with this in Proxylab!
o … but your code should NOT crash!
Handle errors gracefully
o Indicate when errors happen
o They may be recoverable, you may have to terminate
o Remember to free any resources in use
o Else, suffer the wrath of a thousand unicorns
o … and our sadistic style-grading.
Solution 1 : Use CS:APP Wrappers
o
http://csapp.cs.cmu.edu/public/1e/ics/code/src/csapp.c
o
It Has wrapper methods for all core system calls
o
Explicitly checks for return values and then calls unix_error if something went wrong
void *Malloc(size_t size)
{
void *p;
if ((p = malloc(size)) == NULL)
unix_error("Malloc error");
return p;
}
o
Copy/paste required wrappers in source code, since we will accept only
single files in earlier labs.
o
Definitely include this file in your proxy lab submission!
Solution 2: Write your own checks
o
Example: file IO functions
o
fopen: open a given file in a given
mode (read/write/etc)
o fclose: close file associated with given
stream
o fscanf: read data from the stream,
store according to parameter format
o
Error-codes:
o
fopen: return NULL
o
fclose: EOF indicated
o
fscanf: return fewer matched arguments, set
error indicator
FILE *pfile;
// file pointer
if (!(pfile = fopen(“myfile.txt”, “r”)))
{
printf(“Could not find file. Opening
default!”);
pfile = fopen(“default.txt”, “r”);
}
o
May be useful for Cache lab!
Compilation: Using gcc
o
Used to compile C/C++ projects:
o List the files that will be compiled to form an executable
o Specify options via flags
o Use man gcc for more details
o
Important Flags:
o -g: produce debug information (important; used by gdb/gdbtui/valgrind)
o -Werror: treat all warnings as errors (this is our default)
o -Wall/-Wextra: enable all construction warnings
o -pedantic: indicate all mandatory diagnostics listed in C-standard
o -O1/-O2: optimization levels
o -o <filename>: name output binary file ‘filename’
o
Example:
o
gcc -g -Werror -Wall -Wextra -pedantic foo.c bar.c -o baz
Compilation: make
o Easy way to automate bug shell command with lots of flags and files
o Makefiles
allow you to use a single operation to compile different files
together
o Efficient, because it only recompiles updated files
o Lab handouts come with a Makefile:
Don’t change them
o make reads Makefile and compiles your project
o See
http://www.andrew.cmu.edu/course/15-123kesden/index/lecture_index.html for more details on how to ‘make’a
Makefile
Debugging: gdbtui
o
Allows you to see source
o
Compile with –g debug flag
o
Example: gcc –g –m32 myprog.c
–o myprog
o
Run using gdbtui myprog
o
layout src/asm/regs/split –
To display the source / assembly / registers /
source & assembly layout
o
focus src/asm/regs
Make the source / assembly / registers
window active for scrolling
Debugging: valgrind
o
Use it to Find and eliminate memory errors, detect memory leaks
o
Common errors you can fix:
o
Illegal read/write errors
o
Use of uninitialized values
o
Illegal frees
o
Double frees
o
Overlapping source/destination addresses
o
Use gcc with –g to get line number of leaks
o
Use valgrind --leak-check=full for thoroughness
Debugging: Small tip
#ifdef DEBUG
# define dbg_printf(...) printf(__VA_ARGS__)
#else
# define dbg_printf(...)
#endif
Use this to easily wither print or not print
without having to comment out print
statements each time!
Version Control
o
You should use it. Now.
o
Avoid suffering during large labs (malloc, proxy)
o
Basic ideas:
o
o
o
o
Complete record of everything that happened in your code repository
Ability to create branches to test new components of code
Ease in sharing code with others
Well, outside of 213 of course…
Version Control Basics
o
git init:
o
o
o
git status:
o
o
o
Show working tree-status
Untracked files, staged files
git add <file_name>
o
o
o
Create a new repository
Indicated by .git file
Stage a file to be committed (does not perform the commit)
git add . stages all files in current directory
git commit
o
o
Make a commit from all the stage files
git commit -m “Commit message”
Warning
Be cautious when rewinding
commits!!!
Follow online usage instructions
carefully!
Use Stack Overflow,
http://try.github.io,
man pages
Style
o Good documentation
o Header comments, large blocks, tricky bits
o Check error/failure conditions
Must program robustly
o 80 chars per line: Use grep '.\{80,\}' filename to find lines more than 80 chars
o No memory or file descriptor leaks
o Use interfaces for data structures (Don’t repeat code)
o Modularity of code
o No magic numbers
o Use #define
o Consistency and whitespace
o http://cs.cmu.edu/~213/codeStyle.html
Notes
o Go to the C Boot Camp if you have any doubts!
o C Boot Camp:
Time: TBD
o Date: TBD
o Location: TBD
o
o We are style grading from Cache lab onwards!
DEMO
Acknowledgements
o Derived from recitation slides by Arjun Hans, Jack Biggs
o ftp://ftp.gnu.org/old-gnu/Manuals/gdb/html_chapter/gdb_19.html
o http://csapp.cs.cmu.edu/
o xkcd
Download