Activity · 2
Four Bugs in a Client
CSCE 313 · Introduction to Computer Systems
- Format
- In class, supervised
- Time
- 30 minutes
1. What you are doing
client.cpp starts four worker programs with fork() and exec(), then collects
them. It compiles cleanly and it is wrong in four places.
Every one of the four is a mistake people actually make in Lab 2. You are debugging someone else’s client so that next week you can debug your own.
There is no new material here. If you have started Lab 2 Task 1, you have met all four already.
2. Rules
What you may use: the Lab 2 handout, your own Lab 2 work, the man pages,
and your lecture notes. You may talk to the person next to you about ideas.
The code you submit must be yours.
3. Get your repository
- Sign in to classroom50.org with your GitHub account.
- Accept the activity: https://classroom50.org/CSCE-313-FA26/csce-313-fa26/assignments/activity-2/accept.
- Clone it and build:
git clone https://github.com/CSCE-313-FA26/<your-activity-2-repository>.git
cd <your-activity-2-repository>
make
Only g++ is needed. There is no clang and no LLVM IR in this activity.
4. What you are given
| Path | What it is |
|---|---|
client.cpp |
The only file you change. All four bugs are here. |
worker.cpp |
The program the client starts. Correct — do not change it. |
Makefile |
Builds both. Do not change it. |
worker.cpp stands in for Lab 2’s finance, logging and file servers: a separate
program, started with arguments, that reports who it is and then exits with a
status. It reads one flag:
./worker -n 2 # prints its line, then exits with status 2
Read it. It is short, and it tells you exactly what the client has to get right.
5. What a correct run looks like
$ make
$ ./client
client pid 4021 starting 4 workers
worker 0 pid 4022 parent 4021
worker 1 pid 4023 parent 4021
worker 2 pid 4024 parent 4021
worker 3 pid 4025 parent 4021
client reaped pid 4022 exit 0
client reaped pid 4023 exit 1
client reaped pid 4024 exit 2
client reaped pid 4025 exit 3
client done, reaped 4
Four things have to be true, and each one is a separate bug:
- The workers run at all.
- There are exactly four of them, and the client is still alive to reap them.
- Each worker is told its own index — 0, 1, 2, 3, not the same number four times.
- The client reaps every child — all four, not just the first — and reports the status each one exited with.
Your PIDs will differ. The lines may interleave in a different order — workers and the client run at the same time, so a reaped line can appear before another worker’s line. That is normal and not a bug. Only the four things above are checked.
6. How to work
Run it first. Do not read for bugs — let the program tell you.
make
./client
Fix the first thing it complains about, run it again, and see what changes. Each fix makes the next symptom visible. All four are small; none needs more than a line or two.
7. Submitting
Commit and push. The autograder runs on every push, so push as often as you like and read the result.
git add client.cpp
git commit -m "activity 2"
git push
A green check means the checks passed. A red X means they did not — open it and read the message. Points are awarded per bug fixed, so a partly-fixed client is worth partial credit.
| What the grader says | What it means |
|---|---|
does not compile |
Fix the error g++ prints, then push again |
no worker ever ran |
execvp could not find the program it was given |
the client exec'd itself |
The exec is not guarded — the parent reached it too |
produced N worker lines, expected 4 |
Some workers never started |
worker indices were … |
Each worker must be told its own index |
only N of 4 children were reaped |
One wait() collects one child |
nothing was reaped |
The client never called wait() |
8. If you finish early
None of this is submitted — it is here if you have time left.
- Delete the
perror/exitpair afterexecvpand give the worker a name that does not exist. What does the child do now, and how many workers get reaped? - Have the worker exit with
200 + indexinstead. What does the client report, and why is it not what you wrote? (man 2 wait, and look atWEXITSTATUS.) - Print something in the client immediately after
fork()but outside theif (pid == 0). How many times does it appear, and from which processes? - Replace
wait()withwaitpid()so the children are reaped in the order you started them. Does the output become fully deterministic? Which part still is not, and why?