# Common Compiler Troubleshooting Guide ## Installation Issues ### Problem: "gcc: command not found" **Solution**: Install GCC ```bash # Ubuntu/Debian sudo apt-get install build-essential # Fedora/RHEL sudo dnf install gcc # Arch sudo pacman -S gcc ``` ### Problem: "nasm: command not found" **Solution**: Install NASM assembler ```bash # Ubuntu/Debian sudo apt-get install nasm # Fedora/RHEL sudo dnf install nasm # Arch sudo pacman -S nasm ``` ### Problem: "fatal error: bits/libc-header-start.h: No such file" **Cause**: Missing 32-bit development libraries **Solution**: Install 32-bit support ```bash # Ubuntu/Debian sudo apt-get install gcc-multilib # Fedora/RHEL sudo dnf install glibc-devel.i686 libgcc.i686 ``` --- ## Compilation Issues ### Problem: Compiler fails to build **Error**: ``` gcc -o common common.c common.c:15:10: fatal error: stdio.h: No such file or directory ``` **Solution**: Install build essentials ```bash sudo apt-get install build-essential ``` ### Problem: "Permission denied" when running compiler **Solution**: Make compiler executable ```bash chmod +x ./common ``` Or run directly: ```bash gcc -o common common.c ./common source.cm output.asm ``` --- ## Assembly Issues ### Problem: "error: invalid combination of opcode and operands" **Cause**: NASM version incompatibility or corrupt assembly output **Debug Steps**: 1. Check assembly output: ```bash ./common source.cm output.asm cat output.asm ``` 2. Verify NASM version: ```bash nasm -version # Should be 2.x or higher ``` 3. Try manual assembly: ```bash nasm -f elf32 output.asm -o output.o ``` ### Problem: "undefined reference to function_name" **Cause**: Function called but not defined or linked **Solutions**: 1. **Missing function definition**: ```c // Declare AND define the function int32 helper(int32 x) { return x * 2; } ``` 2. **C library function not linked**: ```bash # Make sure you're linking with gcc gcc -m32 output.o -o program # NOT: ld output.o -o program ``` 3. **External library needed**: ```bash gcc -m32 output.o -lm -o program # Link math library ``` --- ## Linker Issues ### Problem: "cannot find -lgcc_s" **Cause**: Missing 32-bit GCC support libraries **Solution**: ```bash sudo apt-get install gcc-multilib ``` ### Problem: "/usr/bin/ld: i386 architecture of input file is incompatible with i386:x86-64" **Cause**: Mixing 32-bit and 64-bit object files **Solution**: Ensure consistent 32-bit compilation: ```bash nasm -f elf32 output.asm -o output.o # Must be elf32 gcc -m32 output.o -o program # Must use -m32 ``` ### Problem: "undefined reference to main" **Cause**: No main function in source **Solution**: Add main function: ```c int32 main(void) { // Your code here return 0; } ``` --- ## Runtime Issues ### Problem: Segmentation fault **Common Causes**: 1. **Null pointer dereference**: ```c int32 *ptr = 0; *ptr = 42; // CRASH: dereferencing NULL ``` **Fix**: Check pointers before dereferencing ```c if (ptr != 0) { *ptr = 42; } ``` 2. **Array out of bounds**: ```c int32 arr[10]; arr[10] = 5; // CRASH: index 10 is out of bounds (0-9) ``` **Fix**: Check array bounds ```c if (index < 10) { arr[index] = 5; } ``` 3. **Stack overflow (infinite recursion)**: ```c int32 recurse(int32 n) { return recurse(n); // CRASH: no base case } ``` **Fix**: Add base case ```c int32 recurse(int32 n) { if (n <= 0) return 0; return recurse(n - 1); } ``` 4. **Writing to read-only memory**: ```c uint8 *str = "constant"; str[0] = 'C'; // CRASH: string literals are read-only ``` **Fix**: Use array for modifiable strings ```c uint8 str[20]; str[0] = 'C'; // OK ``` ### Problem: Wrong output values **Debug Steps**: 1. **Check integer overflow**: ```c int8 x = 127; x = x + 1; // Wraps to -128 ``` 2. **Check division by zero**: ```c int32 result = 10 / 0; // Undefined behavior ``` **Fix**: ```c if (divisor != 0) { result = dividend / divisor; } ``` 3. **Check type truncation**: ```c int32 large = 1000; uint8 small = (uint8)large; // Truncated to 232 (1000 % 256) ``` ### Problem: Program hangs / infinite loop **Common Causes**: 1. **Loop condition never false**: ```c uint32 i = 10; while (i >= 0) { // INFINITE: unsigned i never < 0 i = i - 1; } ``` **Fix**: ```c int32 i = 10; while (i >= 0) { i = i - 1; } ``` 2. **Missing loop increment**: ```c for (int32 i = 0; i < 10; ) { // Missing i++ // ... } ``` --- ## Compiler Error Messages ### "line N: syntax error near 'token'" **Causes**: - Missing semicolon - Mismatched braces/parentheses - Invalid expression syntax **Debug**: 1. Check line N and surrounding lines 2. Look for missing `;` on previous line 3. Count braces: `{` should match `}` 4. Check operator usage **Example**: ```c int32 x = 10 // ERROR: missing semicolon int32 y = 20; ``` ### "line N: Unknown char 'X'" **Cause**: Invalid character in source **Common Examples**: - Smart quotes: `"` `"` instead of `"` - Non-ASCII characters - Tab characters in wrong places **Fix**: Use plain ASCII text editor ### "line N: expected expression" **Cause**: Invalid or incomplete expression **Example**: ```c int32 x = ; // ERROR: no expression after = int32 y = + 5; // ERROR: + needs left operand ``` ### "too many locals" **Cause**: More than 256 local variables in a function **Solution**: 1. Reduce number of variables 2. Use arrays instead of individual variables 3. Split into multiple functions ### "too many strings" **Cause**: More than 512 string literals in program **Solution**: 1. Reuse string literals 2. Build strings programmatically 3. Use character arrays --- ## Debugging Techniques ### Print Debugging ```c void printf(uint8 *fmt, ...); int32 main(void) { int32 x = 10; printf("x = %d\n", x); // Print values int32 *ptr = &x; printf("ptr = %p, *ptr = %d\n", ptr, *ptr); // Print pointers return 0; } ``` ### Check Assembly Output ```bash ./common source.cm output.asm less output.asm # Review generated assembly ``` Look for: - Correct function labels - Proper stack setup - Expected instructions ### Use GDB ```bash # Compile with debug info gcc -m32 -g output.o -o program # Run in debugger gdb ./program # GDB commands: (gdb) break main # Set breakpoint at main (gdb) run # Run program (gdb) next # Step to next line (gdb) print x # Print variable x (gdb) backtrace # Show call stack (gdb) quit # Exit gdb ``` ### Valgrind (Memory Errors) ```bash # Install valgrind sudo apt-get install valgrind # Run with valgrind valgrind --leak-check=full ./program ``` --- ## Common Mistakes ### 1. Assignment in Condition **Wrong**: ```c if (x = 5) { // Assigns 5 to x, always true // ... } ``` **Right**: ```c if (x == 5) { // Compares x to 5 // ... } ``` ### 2. Infinite Loop with Unsigned **Wrong**: ```c for (uint32 i = 10; i >= 0; i--) { // Infinite: unsigned never < 0 // ... } ``` **Right**: ```c for (int32 i = 10; i >= 0; i--) { // ... } ``` ### 3. Pointer vs. Value **Wrong**: ```c void increment(int32 x) { x = x + 1; // Only modifies local copy } int32 val = 5; increment(val); // val is still 5 ``` **Right**: ```c void increment(int32 *x) { *x = *x + 1; // Modifies through pointer } int32 val = 5; increment(&val); // val is now 6 ``` ### 4. Array Decay **Confusing**: ```c int32 arr[10]; int32 *ptr = arr; // arr decays to pointer // arr and &arr are different: arr // Pointer to first element (type: int32*) &arr // Pointer to entire array (type: int32(*)[10]) ``` ### 5. String Modification **Wrong**: ```c uint8 *str = "Hello"; str[0] = 'h'; // CRASH: string literal is read-only ``` **Right**: ```c uint8 str[20] = "Hello"; // Array, modifiable str[0] = 'h'; // OK ``` --- ## Performance Issues ### Slow Compilation **Causes**: - Very large source file - Many string literals **Solutions**: - None (no optimization flags) - Split code into modules (not supported in single-file compiler) ### Slow Execution **Common Causes**: 1. **Inefficient algorithms**: ```c // O(n²) - slow for (int32 i = 0; i < n; i++) for (int32 j = 0; j < n; j++) // ... ``` 2. **Excessive function calls**: ```c // Fibonacci - exponential time int32 fib(int32 n) { if (n <= 1) return n; return fib(n-1) + fib(n-2); // Recomputes same values } ``` **Fix**: Use iterative version or memoization 3. **No optimizations**: The compiler doesn't optimize. Write efficient code. --- ## Getting Help ### Information to Provide When asking for help, include: 1. **Source code** (minimal example that reproduces issue) 2. **Compilation command** used 3. **Full error message** (copy-paste, not screenshot) 4. **System information**: ```bash uname -a gcc --version nasm -version ``` ### Minimal Example Reduce your code to the smallest program that shows the problem: ```c // Minimal example showing segfault int32 main(void) { int32 *ptr = 0; *ptr = 42; // Crash here return 0; } ``` ### Check Examples First Before reporting a bug, verify the example programs work: ```bash make test make examples ``` If examples work but your code doesn't, the issue is likely in your code, not the compiler. --- ## Known Issues ### 64-bit Types **Issue**: 64-bit arithmetic truncates to 32 bits ```c uint64 x = 5000000000; // Stored as 64-bit uint64 y = x * 2; // Multiplied as 32-bit, overflow ``` **Workaround**: Use 32-bit types or implement 64-bit arithmetic manually ### Single File Limitation **Issue**: Cannot split code across multiple files **Workaround**: Put all code in one file, use forward declarations ### No Preprocessor **Issue**: No `#define`, `#include`, etc. **Workaround**: - Use const variables instead of #define - Copy/paste shared code - Write wrapper script to concatenate files --- ## Environment-Specific Issues ### WSL (Windows Subsystem for Linux) Usually works fine. If issues: ```bash sudo apt update sudo apt install gcc-multilib nasm ``` ### macOS **Problem**: macOS doesn't support Linux ELF32 **Solution**: Use a Linux VM or Docker container ### 64-bit Only Systems **Problem**: No 32-bit support installed **Solution**: Install multilib packages (see Installation Issues above) --- *For more help, see the full manual (MANUAL.md) or examples (examples/)*