Operating Systems 2014F: Tutorial 4: Difference between revisions
| No edit summary | No edit summary | ||
| Line 4: | Line 4: | ||
| # Compile the program prog.c using <tt>gcc -O2 prog.c -o prog-dyn</tt> and run prog-dyn.  What does it do? | # Compile the program prog.c using <tt>gcc -O2 prog.c -o prog-dyn</tt> and run prog-dyn.  What does it do? | ||
| # Statically compile and optimize prog.c by running <tt>gcc -O2 -static prog.c -o prog-static</tt>.  How does the size compare with <tt>prog</tt>? | # Statically compile and optimize prog.c by running <tt>gcc -O2 -static prog.c -o prog-static</tt>.  How does the size compare with <tt>prog</tt>? | ||
| # See what system calls prog-static produces by running <tt>strace -o static.log ./prog-static</tt>.  Do the same for <tt>prog-dyn</tt>.  Which version generates more system calls? | # See what system calls prog-static produces by running <tt>strace -o syscalls-static.log ./prog-static</tt>.  Do the same for <tt>prog-dyn</tt>.  Which version generates more system calls? | ||
| # See what library calls prog-static produces by running <tt>ltrace -o library-static.log ./prog-static</tt>.  Do the same for <tt>prog-dyn</tt>.  Which version generates more library calls?  (If ltrace isn't installed, run <tt>sudo apt-get install ltrace</tt>) | |||
| # Using the <tt>nm</tt> command, see what symbols are defined in prog-static and prog-dyn. | # Using the <tt>nm</tt> command, see what symbols are defined in prog-static and prog-dyn. | ||
| # Run the command <tt>gcc -c -O2 prog.c</tt> to produce an object file.  What file was produced?  What symbols does it define? | # Run the command <tt>gcc -c -O2 prog.c</tt> to produce an object file.  What file was produced?  What symbols does it define? | ||
Latest revision as of 14:37, 26 September 2014
In this tutorial you will be learning how address spaces and segments are present on modern Linux systems.
For hello.c, syscall-hello.c, and csimpleshell.c (from Tutorial 2) do the following (substituting the appropriate source file for prog.c):
- Compile the program prog.c using gcc -O2 prog.c -o prog-dyn and run prog-dyn. What does it do?
- Statically compile and optimize prog.c by running gcc -O2 -static prog.c -o prog-static. How does the size compare with prog?
- See what system calls prog-static produces by running strace -o syscalls-static.log ./prog-static. Do the same for prog-dyn. Which version generates more system calls?
- See what library calls prog-static produces by running ltrace -o library-static.log ./prog-static. Do the same for prog-dyn. Which version generates more library calls? (If ltrace isn't installed, run sudo apt-get install ltrace)
- Using the nm command, see what symbols are defined in prog-static and prog-dyn.
- Run the command gcc -c -O2 prog.c to produce an object file. What file was produced? What symbols does it define?
- Look at the assembly code of the program by running gcc -S -O2 prog.c.  What file was produced?  Identify the following:
- A function call
- A system call (if any)
- A global/static variable (if any)
- A local variable
 
- Disassemble the object file using objdump -d. How does this disassembly compare with the output from gcc -S?
- Examine the headers of object file, dynamically linked executable, and the statically linked executable using objdump -h
- Examine the contents of object file, dynamically linked executable, and the statically linked executable using objdump -s
- Re-run all of the previous gcc commands adding the "-v" flag. What is all of that output?
- (optional) Look up the documentation for each of the system calls made by the static versions of the programs. You may need to append a 2 to the manpage invocation, e.g. "man 2 write" gets you the write system call documentation.
Code
hello.c
#include <stdio.h>
int main(int argc, char *argv[]) {
        printf("Hello world!\n");
        return 0;
}
syscall-hello.c
#include <unistd.h>
#include <sys/syscall.h>
char *buf = "Hello world!\n";
int main(int argc, char *argv) {
        size_t result;
        /* "man 2 write" to see arguments to write syscall */
        result = syscall(SYS_write, 1, buf, 13);
        return (int) result;
}