Explain the Wrong Report
Prerequisites and supported environment
Section titled “Prerequisites and supported environment”Finish all five Debugging Foundations lessons first. Work inside the Ubuntu Desktop 24.04.4 LTS x86-64 course VM with GCC 13.x and GDB 15.x. The examples were executed with GCC 13.3 and GDB 15.1; address values and library messages are not fixed answers.
The artifact contains source, small integer datasets, a build script, and checksums. It reads a file you name and prints a summary. Only debug this supplied local program. It needs no network after download, no administrator privileges, and no more resources than the earlier C exercises.
Preserve the archive and your original extraction. You’ll make the correction in a separate source file, so recovering the baseline never depends on remembering what you edited.
Download and verify
Section titled “Download and verify”Download debugging-report-v1.0.0.tar into ~/underdunn-course/downloads.
Shell input:
cd ~/underdunn-course/downloadssha256sum debugging-report-v1.0.0.tarExpected archive digest:
25f3a207fe0620960a3f441b519c1b55b67bc5b247f9f1c0adba28e775c330e8 debugging-report-v1.0.0.tarStop if it differs. Once verified, extract into a new directory:
mkdir -p ~/underdunn-course/labs/debugging-reporttar -xf debugging-report-v1.0.0.tar -C ~/underdunn-course/labs/debugging-reportcd ~/underdunn-course/labs/debugging-report/debugging-report-v1.0.0sha256sum -c CHECKSUMS.sha256sh build.shEvery checksum should report OK, and the build should finish without warnings. build.sh invokes the familiar compiler with -O0 -g; the executable is built in your guest rather than supplied from a different machine.
Establish the behavior before choosing a stop
Section titled “Establish the behavior before choosing a stop”Read TASK.md, the source, and the supplied datasets. The intended rule is simple: positive integers contribute to both the count and total; zero and negative integers contribute to neither. An empty file should produce zero for both. Inputs here are small integer records; malformed text and arithmetic overflow are outside this task.
The input loop uses fscanf(input, "%d", &value). That call reads one integer from the open file into value; a return of one means one conversion succeeded. The loop continues while that happens. You don’t need to redesign file parsing for this investigation, but you do need to distinguish reading a record from deciding whether it contributes to the report.
Before running records.txt, predict the count and total. Then run the baseline and compare its output and exit status. Choose an intermediate value to inspect in GDB to locate the discrepancy.
Hint 1: choose between explanations
Separate record selection from accumulation. A wrong total might come from including the wrong record, losing an earlier total, or performing the wrong arithmetic. Find the first record where intended and actual state disagree.
Hint 2: choose an observation
GDB can stop inside summarize. Inspect initialized locals, then choose either value-change observation or stepping across one record at a time. Keep each observed total associated with the record that produced it.
Hint 3: one possible session
Start the baseline in the shell:
gdb -q ./reportThen use GDB input:
break report.c:7run records.txtprint totalwatch totalcontinuecontinueprint valueprint totalLine seven in the verified source is the input loop, after initialization. Check your own listing before relying on that number in an edited file. These stops give you two total changes. Explain them against the specification before deciding on a correction.
Diagnose, correct, and test
Section titled “Diagnose, correct, and test”Stop at the first incorrect total in GDB and identify the operation that changed it. Compare that operation with the positive-record rule before making the correction.
Quit GDB before building the correction. Copy report.c to report-fixed.c, make the smallest change justified by the specification, and compile it to report-fixed using the same warning and debugging options. Don’t replace the baseline executable.
Predict the corrected behavior for records.txt, positive.txt, and nonpositive.txt, then test all three. Create an empty input with touch empty.txt in this fresh lab directory and test it too. If that name already exists, verify that it is empty before using it. Explain which case demonstrates the correction and which cases guard behavior that should remain unchanged.
Hint 1: keep the correction narrow
Compare the condition controlling the count with the condition controlling the total. Both are supposed to describe the same selected records.
Hint 2: evaluate the regression set
A positive-only file cannot establish correct treatment of negative records. Conversely, a program that always prints zero could appear correct on an empty file. You need both kinds of test.
Hint 3: build and run the separate copy
After making your justified edit, use shell input:
gcc -std=c11 -Wall -Wextra -Wpedantic -O0 -g report-fixed.c -o report-fixed./report-fixed records.txt./report-fixed positive.txt./report-fixed nonpositive.txt./report-fixed empty.txtCompare each result with your own prediction. A successful compiler exit does not establish that the selection rule was repaired.
Check two observations
Section titled “Check two observations”Use the unmodified program and records.txt. Enter the total immediately after processing its second record and the final reported positive count. Use decimal values, preserving a minus sign if present.
These fields check the baseline observations. Use the tests above to check your correction.
Optional: try a fresh dataset
Section titled “Optional: try a fresh dataset”Close the hints and use fresh.txt. Predict both baseline and corrected behavior. Choose your own stopping points and establish the first disagreement, then verify your correction without following a command transcript. Use the hints again if you need them.
Feedback after the fresh attempt
Check the contribution of the negative record separately from the zero. If you used a value-change watchpoint, explain why a record might be processed without changing the total. If a prediction fails, return to the per-record rule before making another edit.
Check your result
Section titled “Check your result”The checker should accept both baseline observations. The corrected program should count and sum only positive records: positive-only input keeps its expected result, while nonpositive and empty inputs give zero count and total. If a case differs, stop at the first record where the total changes incorrectly and check the condition.
Common failures, reset, and cleanup
Section titled “Common failures, reset, and cleanup”- Checksum failure: stop and obtain a fresh archive. Don’t analyze an artifact whose identity is uncertain.
- File-open error: check the working directory and dataset name. The program expects one data-file argument.
- Breakpoint misses: check the source/build identity and inspect the current line. Use the original baseline for the observation fields.
- Watchpoint cannot be installed: use the software fallback or source stepping from Find Where a Value Goes Wrong.
- A correction made things worse: keep that attempt and extract the original archive into a new directory, then rebuild. Keep any modified source you want before resetting.
For a reset, create a fresh destination before extracting:
cd ~/underdunn-course/labs/debugging-reportmkdir reset-01tar -xf ~/underdunn-course/downloads/debugging-report-v1.0.0.tar -C reset-01cd reset-01/debugging-report-v1.0.0sha256sum -c CHECKSUMS.sha256sh build.shUse a new reset number if reset-01 already exists. For cleanup, quit GDB and remove only the generated report and report-fixed executables from your verified lab directory. Keep the source attempts if you want to revisit them; the small archive is your recovery copy.
Next, bring this observation method into the Program Investigation Capstone.