demumble.cc
Go to the documentation of this file.
1 #include <stddef.h>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include <string.h>
5 #include <algorithm>
6 
7 extern "C" {
8 char* __cxa_demangle(const char* mangled_name,
9  char* buf,
10  size_t* n,
11  int* status);
12 
13 typedef void* (*malloc_func_t)(size_t);
14 typedef void (*free_func_t)(void*);
15 char* __unDName(char* buffer,
16  const char* mangled,
17  int buflen,
18  malloc_func_t memget,
19  free_func_t memfree,
20  unsigned short int flags);
21 }
22 
23 const char kDemumbleVersion[] = "1.0.0.git";
24 
25 static void print_help(FILE* out) {
26  fprintf(out,
27 "usage: demumble [options] [symbols...]\n"
28 "\n"
29 "if symbols are unspecified, reads from stdin.\n"
30 "\n"
31 "options:\n"
32 " -m only print mangled names that were demangled, omit other output\n"
33 " -u use unbuffered output\n"
34 " --version print demumble version (\"%s\")\n", kDemumbleVersion);
35 }
36 
37 static bool starts_with(const char* s, const char* prefix) {
38  return strncmp(s, prefix, strlen(prefix)) == 0;
39 }
40 
41 static void print_demangled(const char* s) {
42  const char* cxa_in = s;
43  if (starts_with(s, "__Z") || starts_with(s, "____Z"))
44  cxa_in += 1;
45  if (char* itanium = __cxa_demangle(cxa_in, NULL, NULL, NULL)) {
46  printf("%s", itanium);
47  free(itanium);
48  } else if (char* ms = __unDName(NULL, s, 0, &malloc, &free, 0)) {
49  printf("%s", ms);
50  free(ms);
51  } else {
52  printf("%s", s);
53  }
54 }
55 
56 static bool is_mangle_char_posix(char c) {
57  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
58  (c >= '0' && c <= '9') || c == '_';
59 }
60 
61 static bool is_mangle_char_win(char c) {
62  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') ||
63  (c >= '0' && c <= '9') || strchr("?_@$", c);
64 }
65 
66 static bool is_plausible_itanium_prefix(char* s) {
67  // Itanium symbols start with 1-4 underscores followed by Z.
68  // strnstr() is BSD, so use a small local buffer and strstr().
69  const int N = 5; // == strlen("____Z")
70  char prefix[N + 1];
71  strncpy(prefix, s, N); prefix[N] = '\0';
72  return strstr(prefix, "_Z");
73 }
74 
75 static char buf[8192];
76 int main(int argc, char* argv[]) {
77  enum { kPrintAll, kPrintMatching } print_mode = kPrintAll;
78  while (argc > 1 && argv[1][0] == '-') {
79  if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
81  return 0;
82  } else if (strcmp(argv[1], "-m") == 0) {
83  print_mode = kPrintMatching;
84  } else if (strcmp(argv[1], "-u") == 0) {
85  setbuf(stdout, NULL);
86  } else if (strcmp(argv[1], "--version") == 0) {
87  printf("%s\n", kDemumbleVersion);
88  return 0;
89  } else if (strcmp(argv[1], "--") == 0) {
90  --argc;
91  ++argv;
92  break;
93  } else {
94  fprintf(stderr, "demumble: unrecognized option `%s'\n", argv[1]);
96  return 1;
97  }
98  --argc;
99  ++argv;
100  }
101  for (int i = 1; i < argc; ++i) {
102  print_demangled(argv[i]);
103  printf("\n");
104  }
105  if (argc == 1) { // Read stdin instead.
106  // By default, don't demangle types. Mangled function names are unlikely
107  // to appear in text for since they start with _Z (or ___Z) or ?? / ?$ / ?@.
108  // But type manglings can be regular words ("Pi" is "int*").
109  // (For command-line args, do try to demangle types though.)
110  while (fgets(buf, sizeof(buf), stdin)) {
111  bool need_separator = false;
112  char* cur = buf;
113  char* end = cur + strlen(cur);
114 
115  while (cur != end) {
116  size_t special = strcspn(cur, "_?");
117  if (print_mode == kPrintAll)
118  printf("%.*s", static_cast<int>(special), cur);
119  else if (need_separator)
120  printf("\n");
121  need_separator = false;
122  cur += special;
123  if (cur == end)
124  break;
125 
126  size_t n_sym = 0;
127  if (*cur == '?')
128  while (cur + n_sym != end && is_mangle_char_win(cur[n_sym]))
129  ++n_sym;
131  while (cur + n_sym != end && is_mangle_char_posix(cur[n_sym]))
132  ++n_sym;
133  else {
134  if (print_mode == kPrintAll)
135  printf("_");
136  ++cur;
137  continue;
138  }
139 
140  char tmp = cur[n_sym];
141  cur[n_sym] = '\0';
143  need_separator = true;
144  cur[n_sym] = tmp;
145 
146  cur += n_sym;
147  }
148  }
149  }
150 }
__unDName
char * __unDName(char *buffer, const char *mangled, int buflen, malloc_func_t memget, free_func_t memfree, unsigned short int flags)
Definition: undname.c:1623
is_mangle_char_posix
static bool is_mangle_char_posix(char c)
Definition: demumble.cc:56
gen_build_yaml.out
dictionary out
Definition: src/benchmark/gen_build_yaml.py:24
main
int main(int argc, char *argv[])
Definition: demumble.cc:76
demumble_test.stdout
stdout
Definition: demumble_test.py:38
print_demangled
static void print_demangled(const char *s)
Definition: demumble.cc:41
__cxa_demangle
char * __cxa_demangle(const char *mangled_name, char *buf, size_t *n, int *status)
Definition: cxa_demangle.cpp:4927
string.h
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
printf
_Use_decl_annotations_ int __cdecl printf(const char *_Format,...)
Definition: cs_driver.c:91
status
absl::Status status
Definition: rls.cc:251
demumble_test.stdin
stdin
Definition: demumble_test.py:37
kDemumbleVersion
const char kDemumbleVersion[]
Definition: demumble.cc:23
python_utils.port_server.stderr
stderr
Definition: port_server.py:51
c
void c(T a)
Definition: miscompile_with_no_unique_address_test.cc:40
end
char * end
Definition: abseil-cpp/absl/strings/internal/str_format/float_conversion.cc:1008
malloc_func_t
void *(* malloc_func_t)(size_t)
Definition: demumble.cc:13
buffer
char buffer[1024]
Definition: libuv/docs/code/idle-compute/main.c:8
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
print_help
static void print_help(FILE *out)
Definition: demumble.cc:25
is_plausible_itanium_prefix
static bool is_plausible_itanium_prefix(char *s)
Definition: demumble.cc:66
memory_diff.cur
def cur
Definition: memory_diff.py:83
benchmark.FILE
FILE
Definition: benchmark.py:21
N
#define N
Definition: sync_test.cc:37
absl::flags_internal
Definition: abseil-cpp/absl/flags/commandlineflag.h:40
is_mangle_char_win
static bool is_mangle_char_win(char c)
Definition: demumble.cc:61
starts_with
static bool starts_with(const char *s, const char *prefix)
Definition: demumble.cc:37
prefix
static const char prefix[]
Definition: head_of_line_blocking.cc:28
free_func_t
void(* free_func_t)(void *)
Definition: demumble.cc:14
buf
static char buf[8192]
Definition: demumble.cc:75
autogen_x86imm.tmp
tmp
Definition: autogen_x86imm.py:12
i
uint64_t i
Definition: abseil-cpp/absl/container/btree_benchmark.cc:230


grpc
Author(s):
autogenerated on Fri May 16 2025 02:58:09