NationalSecurityAgency/ghidra · warning

Failed: %s (status %d)

Error message

Failed: %s (status %d)

What it means

In the standalone demangler build with IN_GLIBCPP_V3 defined, each command-line argument is passed to __cxa_demangle(argv[i], NULL, NULL, &status). When the result pointer is NULL the demangle failed; the program prints 'Failed: <input> (status <n>)' to stderr and continues to the next argument. The status comes from __cxa_demangle and encodes the failure class (memory/allocation error vs. invalid mangled name). Note this is a diagnostic message, not a thrown error, and the process still returns 0.

Source

Thrown at GPL/DemanglerGnu/src/demangler_gnu_v2_24/c/cp-demangle.c:5977

#endif

	  /* 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 actually an Itanium-ABI mangled C++ name (typically starting with _Z) before demangling.
  2. Map the status code to its cause: -1 memory/allocation, -2 invalid mangled name, -3 invalid args; -2 means the input is not valid.
  3. Upgrade/use a demangler version matching the compiler that produced the symbols (ABI/compiler version skew causes false failures).
  4. If running a batch, accept that non-C++ symbols legitimately fail and filter them upstream.

Example fix

# before
$ c++filt _Z3foov _invalid_token
Failed: _invalid_token (status -2)

# after - filter to plausible mangled names first
$ echo _Z3foov | grep -E '^_Z' | c++filt
foo()
Defensive patterns

Strategy: validation

Validate before calling

// Only pass plausible Itanium mangled names to the demangler
#include <string.h>
int looksMangled(const char *s) { return s && s[0] == '_' && s[1] == 'Z'; }
if (looksMangled(argv[i])) {
    char *r = __cxa_demangle(argv[i], NULL, NULL, &status);
    ...
}

Type guard

boolean looksLikeItaniumMangled(String s) {
    return s != null && s.startsWith("_Z");
}

Try / catch

// The standalone demangler is a separate process; inspect its exit and stderr.
// Note: with IN_GLIBCPP_V3 the process still returns 0; detect via stderr text:
if (stderr_contains("Failed:") && stderr_contains("(status -2)")) {
    /* input was not a valid mangled name; filter it out and continue */
}

Prevention

When it happens

Trigger: Running the standalone c++filt/demangler binary on a string that __cxa_demangle cannot parse (returns NULL). The input was not a valid Itanium C++ ABI mangled name, or was malformed enough to be rejected. status reflects why (e.g. -2 for invalid, -3 for memory).

Common situations: Feeding plain C symbols, demangled names, or non-C++ input to the demangler; passing a partially-mangled or truncated mangled name; using the wrong demangling style/ABI for the input (e.g. Itanium demangler on MSVC names); version mismatch between the compiler that mangled and the demangler binary.

Related errors


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