Einleitung
Wer Binärdateien unter Linux analysiert oder tief in Stack-Traces eintaucht, stößt unweigerlich auf kryptische Zeichenfolgen. Dahinter verbirgt sich kein Zufall, sondern das sogenannte Name Mangling des C++-Compilers: Um Funktionsüberladung (Overloading), Namespaces und Vorlagen (Templates) auf Linker-Ebene eindeutig abzubilden, transformiert der Compiler Bezeichner in systemspezifische Signaturen. In dieser Praxisanleitung erfahren Sie, wie das GNU-Dienstprogramm c++filt funktioniert und wie Sie unverständliche Symbole im Handumdrehen in lesbare Funktionsdeklarationen zurückverwandeln.
Toolchain einrichten und elementare Symbole auflösen
Das Werkzeug c++filt ist fester Bestandteil der GNU Binary Utilities. Die Installation des entsprechenden Pakets auf einem Ubuntu-System erfolgt über apt-get update -qq && apt-get install -y binutils.

Mit c++filt --version | head -n 2 lässt sich die installierte Programmversion der Binutils verifizieren.
Die primäre Aufgabe von c++filt besteht darin, gemanglete Low-Level-Symbole wieder in die ursprüngliche C++-Syntax aus Klassen-, Namensraum- und Typdefinitionen zu übersetzen.
⚙️ [Zentrale Parameter]
-_, --strip-underscore : Entfernt führende Unterstriche (_) vor dem eigentlichen Demangling-Vorgang.-n, --no-strip-underscore : Belässt führende Unterstriche unverändert im Eingabestring.-p, --no-params : Unterdrückt die Ausgabe der Funktionsparameter und liefert lediglich den reinen Funktionsnamen.-t, --types : Aktiviert das Decodieren von Typdefinitionen neben regulären Funktionsbezeichnern.-s, --format : Definiert ein spezifisches ABI-Format (z. B. Itanium oder GNU) für den Übersetzungsvorgang.

Um ein einfaches, einstelliges Funktionssymbol direkt auf der Konsole aufzulösen, dient der Aufruf c++filt _Z1fv.
Die Ausgabe liefert die ursprüngliche Signatur f(), die eine parameterlose Funktion repräsentiert.

Auch verschachtelte Symbole mit Gültigkeitsbereichen und Parametern lassen sich analysieren; hierfür wird c++filt _ZN4Math3addEii ausgeführt.
Das Tool decodiert den Namespace Math, die enthaltene Methode add sowie die beiden Integer-Argumente und erzeugt das Resultat Math::add(int, int).

Entstehung von Name Mangling und Analyse via nm-Pipeline
Für das Erstellen eigener Testbinärdateien wird die standardmäßige Build-Umgebung benötigt, welche sich über apt-get update -qq && apt-get install -y build-essential einrichten lässt.

Ein kleiner Demonstrationsquelltext mit überladenen Methoden innerhalb eines Namespaces wird mittels cat << 'EOF' > /tmp/demo.cpp erzeugt.

Die Kompilierung des Quellcodes zu einer Objektdatei erfolgt ohne Linker-Durchlauf über das Kommando g++ -c /tmp/demo.cpp -o /tmp/demo.o.

Um die Symboltabelle der generierten Datei zu inspizieren, filtert nm /tmp/demo.o | grep add gezielt nach den implementierten Additionsroutinen.
Das Ergebnis offenbart die internen Compilerbezeichner _ZN10Calculator3addEii und _ZN10Calculator3addEdd, in welchen Datentypen und Namensräume codiert sind.

Durch Verketten der Befehle in einer Unix-Pipeline lassen sich sämtliche Treffer direkt lesbar machen: nm /tmp/demo.o | c++filt | grep add.
Dabei transformiert c++filt die kryptischen Tabelleneinträge vollautomatisch in saubere Deklarationen der Gestalt Calculator::add(int, int) und Calculator::add(double, double).

Komplexe Template-Instanziierungen per Stream auflösen
In der Praxis stellen vor allem Templates mit verschachtelten STL-Containern Entwickler vor Lesbarkeitsprobleme. Folgendes Beispiel wird via cat << 'EOF' > /tmp/template_demo.cpp angelegt.

Der entsprechende Maschinencode wird wiederum als Objektdatei mit g++ -c /tmp/template_demo.cpp -o /tmp/template_demo.o generiert.

Eine Abfrage der Symboltabelle mittels nm /tmp/template_demo.o | grep print verdeutlicht das Ausmaß moderner C++-Typen.
Das erzeugte Mangling-Konstrukt ist extrem unübersichtlich, da sämtliche Allokatoren, String-Typdefinitionen und Containerstrukturen vollständig im Symbolnamen verankert sind.

Schleust man diesen Datenstrom durch das Filterwerkzeug via nm /tmp/template_demo.o | c++filt | grep print, wird die Zeichenkette wieder verständlich.
Das Programm entschlüsselt die gesamte Typhierearchie fehlerfrei und gibt die vollständige Klassensignatur samt Template-Spezialisierung übersichtlich im Terminal aus.

Erweiterte Flags (-p, -t) und automatisierte Protokollanalyse
Standardmäßig zeigt der Aufruf c++filt _ZN10Calculator3addEii die vollständige Signatur einschließlich aller Typangaben.
Die Ausgabe visualisiert die Methode inklusive ihrer formalen Parameterliste (int, int).

Wenn für Skripte oder Übersichten lediglich der Klassenpfad ohne Parameterliste benötigt wird, hilft der Schalter -p im Befehl c++filt -p _ZN10Calculator3addEii.
Durch das Ausblenden der Argumente verkürzt sich das Ergebnis auf das wesentliche Element Calculator::add.

Soll explizit geprüft werden, ob das Symbol auch als reiner Typbezeichner interpretiert werden kann, wird der Modus mit c++filt -t _ZN10Calculator3addEii aufgerufen.
Auch unter diesem Flag bleibt die methodische Struktur erhalten und wird korrekt als Calculator::add(int, int) wiedergegeben.

Ein enormer Vorteil im Debugging-Alltag ist die Fähigkeit des Dienstprogramms, gemischten Text zu parsen: echo 'Fatal error in _ZN10Calculator3addEii at runtime' | c++filt.
Hierbei bleibt der umgebende Text unberührt, während c++filt eingebettete C++-Symbole treffsicher isoliert und im laufenden Textstrom durch den Klartextnamen ersetzt.

Das Zusammenspiel von C++ Name Mangling und dem Demangling-Mechanismus von c++filt bildet ein unverzichtbares Fundament für die Fehlerdiagnose unter Linux.
Ob bei unaufgelösten Referenzen des Linkers (undefined reference) oder unübersichtlichen Fehlerausgaben: Mit c++filt lassen sich Systeminterna jederzeit rasch und präzise dechiffrieren.