Skip to content

Latest commit

 

History

History
79 lines (66 loc) · 2.73 KB

COMMON_ERRORS.md

File metadata and controls

79 lines (66 loc) · 2.73 KB

Common Errors

After installing all the required deps and you run make qemu, you will face this error:

user/sh.c: In function 'runcmd':
user/sh.c:60:1: error: infinite recursion detected [-Werror=infinite-recursion]
   60 | runcmd(struct cmd *cmd)
      | ^~~~~~
user/sh.c:91:5: note: recursive call
   91 |     runcmd(rcmd->cmd);
      |     ^~~~~~~~~~~~~~~~~
user/sh.c:111:7: note: recursive call
  111 |       runcmd(pcmd->left);
      |       ^~~~~~~~~~~~~~~~~~
user/sh.c:118:7: note: recursive call
  118 |       runcmd(pcmd->right);
      |       ^~~~~~~~~~~~~~~~~~~
user/sh.c:97:7: note: recursive call
   97 |       runcmd(lcmd->left);
      |       ^~~~~~~~~~~~~~~~~~
user/sh.c:99:5: note: recursive call
   99 |     runcmd(lcmd->right);
      |     ^~~~~~~~~~~~~~~~~~~
user/sh.c:129:7: note: recursive call
  129 |       runcmd(bcmd->cmd);
      |       ^~~~~~~~~~~~~~~~~
cc1: all warnings being treated as errors
make: *** [user/sh.o] Error 1

This is because in the Makefile CFLAGS, we have the -Werror flag (line 70) which tells the compiler (gcc/clang) to treat all warnings as errors. This means any warnigs that would normally just display a message will instead cause the compilation to fail.

Fix

  1. Go to the file user/sh.c and find the function runcmd(struct cmd *cmd)

  2. Make the following file changes to it:

diff --git a/user/sh.c b/user/sh.c
index 83dd513..7f93bb2 100644
--- a/user/sh.c
+++ b/user/sh.c
// Execute cmd.  Never returns.
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Winfinite-recursion"
void
runcmd(struct cmd *cmd)
{
@@ -129,6 +131,7 @@ runcmd(struct cmd *cmd)
  }
  exit(0);
}
+#pragma GCC diagnostic pop

The key changes are:

  1. Added #pragma GCC diagnostic push to save the current warning settings
  2. Added #pragma GCC diagnostic ignored "-Winfinite-recursion" to disable the specific warning
  3. Added #pragma GCC diagnostic pop to restore the warning settings after the function

This is safe because:

  • Each recursive call is always in a different process (after fork)

  • The recursion will terminate when we hit an EXEC command

  • The shell command structure is inherently recursive (commands can contain other commands)

  • Each path either:

    • Calls exec() which replaces the current process
    • Or exits explicitly
    • Or makes a recursive call in a child process

The pragmas tell the compiler that we understand there's recursion here and it's intentional. This resolves the compilation error while maintaining the correct shell behavior.

Additional Resources