NationalSecurityAgency/ghidra · critical

%s: error: too many @-files encountered\n

Error message

%s: error: too many @-files encountered\n

What it means

The expandargv function processes @file response-file arguments iteratively. A decrementing iteration_limit guards against infinite loops from circular references (e.g. @a includes @b which includes @a). When the limit reaches zero, the tool prints this error and calls xexit(1), terminating immediately.

Source

Thrown at GPL/DemanglerGnu/src/demangler_gnu_v2_41/c/argv.c:406

      /* A dynamically allocated buffer used to hold options read from a
	 response file.  */
      char *buffer;
      /* Dynamically allocated storage for the options read from the
	 response file.  */
      char **file_argv;
      /* The number of options read from the response file, if any.  */
      size_t file_argc;
#ifdef S_ISDIR
      struct stat sb;
#endif
      /* We are only interested in options of the form "@file".  */
      filename = (*argvp)[i];
      if (filename[0] != '@')
	continue;
      /* If we have iterated too many times then stop.  */
      if (-- iteration_limit == 0)
	{
	  fprintf (stderr, "%s: error: too many @-files encountered\n", (*argvp)[0]);
	  xexit (1);
	}
#ifdef S_ISDIR
      if (stat (filename+1, &sb) < 0)
	continue;
      if (S_ISDIR(sb.st_mode))
	{
	  fprintf (stderr, "%s: error: @-file refers to a directory\n", (*argvp)[0]);
	  xexit (1);
	}
#endif
      /* Read the contents of the file.  */
      f = fopen (++filename, "r");
      if (!f)
	continue;
      if (fseek (f, 0L, SEEK_END) == -1)
	goto error;
      pos = ftell (f);

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Flatten nested response files into a single file
  2. Break circular @-file references
  3. Audit the response file chain to identify the loop
  4. Reduce the total number of @-file indirections

Example fix

# before: @outer.txt contains @inner.txt which contains @outer.txt
# after: merge all options into a single flat @all-options.txt
Defensive patterns

Strategy: validation

Validate before calling

// Before calling expandargv, check for circular or excessively nested @-files
#include <sys/stat.h>
static int count_response_file_depth(const char *path, int depth) {
    if (depth > 16) return -1; // arbitrary safety limit
    FILE *f = fopen(path, "r");
    if (!f) return depth;
    char line[4096];
    int max_child = depth;
    while (fgets(line, sizeof(line), f)) {
        char *at = strchr(line, '@');
        if (at && at[1] != '\0' && at[1] != '\n') {
            int d = count_response_file_depth(at + 1, depth + 1);
            if (d < 0) { fclose(f); return -1; }
            if (d > max_child) max_child = d;
        }
    }
    fclose(f);
    return max_child;
}

Prevention

When it happens

Trigger: Response files (@file) are deeply nested or circular; the cumulative count of @-file expansions exceeds iteration_limit. Each @-file encountered decrements the counter; hitting zero triggers the fatal exit.

Common situations: Circular response file references (@a contains @b, @b contains @a); build systems that auto-generate deeply nested response files; accidentally pointing an @file at itself.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/58e549add883deca. Report an issue: GitHub.