NationalSecurityAgency/ghidra · warning

Failed: %s\n

Error message

Failed: %s\n

What it means

In the standard standalone demangler build (without IN_GLIBCPP_V3), cplus_demangle_v3() returned NULL for the input token. The tool prints only the original token (no status code) and continues to the next argument. Same condition as error 31, different build configuration.

Source

Thrown at GPL/DemanglerGnu/src/demangler_gnu_v2_41/c/cp-demangle.c:7313

	  /* Attempt to demangle.  */
#ifdef IN_GLIBCPP_V3
	  s = __cxa_demangle (argv[i], NULL, NULL, &status);
#else
	  s = cplus_demangle_v3 (argv[i], options);
#endif

	  /* If it worked, print the demangled name.  */
	  if (s != NULL)
	    {
	      printf ("%s\n", s);
	      free (s);
	    }
	  else
	    {
#ifdef IN_GLIBCPP_V3
	      fprintf (stderr, "Failed: %s (status %d)\n", argv[i], status);
#else
	      fprintf (stderr, "Failed: %s\n", argv[i]);
#endif
	    }
	}
    }

  return 0;
}

#endif /* STANDALONE_DEMANGLER */

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Confirm the input is a valid Itanium-ABI mangled name (starts with _Z)
  2. Pre-filter input to skip non-mangled symbols
  3. Use `--no-strip-underscore` if underscore handling is wrong

Example fix

// before
echo 'main' | c++filt
// after
echo '_Z3foov' | c++filt
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-filter non-mangled strings to avoid the failure path
static int is_mangled_name(const char *s) {
    if (!s || s[0] != '_') return 0;
    return s[1] == 'Z'; // Itanium ABI
}
for (int i = optind; i < argc; i++) {
    if (!is_mangled_name(argv[i])) {
        printf("%s\n", argv[i]); // pass through unmangled
        continue;
    }
    char *r = cplus_demangle_v3(argv[i], options);
    if (r) { printf("%s\n", r); free(r); }
    else   printf("%s\n", argv[i]);
}

Type guard

static int is_demangleable(const char *s) {
    return s != NULL && s[0] == '_' && s[1] == 'Z';
}

Try / catch

char *demangled = cplus_demangle_v3(mangled_str, options);
if (demangled == NULL) {
    // Not a valid mangled name — use the original string
    output(mangled_str);
} else {
    output(demangled);
    free(demangled);
}

Prevention

When it happens

Trigger: cplus_demangle_v3(argv[i], options) returns NULL for the current argument. The #else branch (non-GLIBCPP_V3) is compiled. The loop continues processing remaining arguments.

Common situations: Feeding non-mangled text or C symbols to c++filt; mangled names from an incompatible ABI; corrupted or truncated mangled strings.

Related errors


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