digitalmars.D - demangle tool
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Apr 09 2009
- grauzone <none example.net> Apr 09 2009
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Apr 09 2009
- Leandro Lucarella <llucax gmail.com> Apr 09 2009
- R <a b.com> Apr 10 2009
- bearophile <bearophileHUGS lycos.com> Apr 10 2009
- Sergey Gromov <snake.scaly gmail.com> Apr 10 2009
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Apr 10 2009
- Michel Fortin <michel.fortin michelf.com> Apr 10 2009
- Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> Apr 10 2009
- Michel Fortin <michel.fortin michelf.com> Apr 11 2009
- Sergey Gromov <snake.scaly gmail.com> Apr 12 2009
- Jason House <jason.james.house gmail.com> Apr 10 2009
I wrote a simple utility (at the bottom of this message) that may help
debugging link-time errors. It reads lines from stdin and writes them
with DMD symbols, if any, demangled.
For example, here's what you see if you add "alias field this;" to Tuple
in std.typecons and try to build the "new, new" Phobos:
obj/posix/debug/unittest/std/file.o: In function
`_D3std4file14__T5slurpTiTdZ5slurpFAyaxAaZAS3std8typecons14__T5TupleTiTdZ5Tuple':
/home/andrei/code/dmd/phobos/std/file.d:1772: undefined reference to
`_D3std8typecons14__T5TupleTiTdZ5Tuple6__initZ'
/home/andrei/code/dmd/phobos/std/file.d:1781: undefined reference to
`_D3std5array51__T8AppenderTAS3std8typecons14__T5TupleTiTdZ5TupleZ8Appender3putMFxS3std8typecons14__T5TupleTiTdZ5TupleZv'
obj/posix/debug/unittest/std/file.o: In function
`_D3std5array88__T8appenderTAS3std8typecons14__T5TupleTiTdZ5TupleTS3std8typecons14__T5TupleTiTdZ5TupleZ8appenderFPAS3std8typecons14__T5TupleTiTdZ5TupleZS3std5array51__T8AppenderTAS3std8typecons14__T5TupleTiTdZ5TupleZ8Appender':
/home/andrei/code/dmd/phobos/std/array.d:578: undefined reference to
`_D3std5array51__T8AppenderTAS3std8typecons14__T5TupleTiTdZ5TupleZ8Appender6__ctorMFNcPAS3std8typecons14__T5TupleTiTdZ5TupleZS3std5array51__T8AppenderTAS3std8typecons14__T5TupleTiTdZ5TupleZ8Appender'
obj/posix/debug/unittest/std/file.o: In function
`_D3std8typecons14__T5tupleTiTdZ5tupleFidZS3std8typecons14__T5TupleTiTdZ5Tuple':
/home/andrei/code/dmd/phobos/std/typecons.d:515: undefined reference to
`_D3std8typecons14__T5TupleTiTdZ5Tuple6__initZ'
collect2: ld returned 1 exit status
--- errorlevel 1
However, if you use "make |& ./demangle.d", you see:
obj/posix/debug/unittest/std/file.o: In function `struct
std.typecons.Tuple!(int, double).Tuple[] std.file.slurp!(int,
double).slurp(immutable(char)[], const(char[]))':
/home/andrei/code/dmd/phobos/std/file.d:1772: undefined reference to `Z
std.typecons.Tuple!(int, double).Tuple.__init'
/home/andrei/code/dmd/phobos/std/file.d:1781: undefined reference to
`void std.array.Appender!(struct std.typecons.Tuple!(int,
double).Tuple[]).Appender.put(const(struct std.typecons.Tuple!(int,
double).Tuple))'
obj/posix/debug/unittest/std/file.o: In function `struct
std.array.Appender!(struct std.typecons.Tuple!(int,
double).Tuple[]).Appender std.array.appender!(struct
std.typecons.Tuple!(int, double).Tuple[], struct
std.typecons.Tuple!(int, double).Tuple).appender(struct
std.typecons.Tuple!(int, double).Tuple[]*)':
/home/andrei/code/dmd/phobos/std/array.d:578: undefined reference to
`_D3std5array51__T8AppenderTAS3std8typecons14__T5TupleTiTdZ5TupleZ8Appender6__ctorMFNcPAS3std8typecons14__T5TupleTiTdZ5TupleZS3std5array51__T8AppenderTAS3std8typecons14__T5TupleTiTdZ5TupleZ8Appender'
obj/posix/debug/unittest/std/file.o: In function `struct
std.typecons.Tuple!(int, double).Tuple std.typecons.tuple!(int,
double).tuple(int, double)':
/home/andrei/code/dmd/phobos/std/typecons.d:515: undefined reference to
`Z std.typecons.Tuple!(int, double).Tuple.__init'
collect2: ld returned 1 exit status
--- errorlevel 1
make: *** [obj/posix/debug/unittest/std/file] Error 1
The line wraps are all garbled, but you get the idea: all symbols quoted
`like this' have been demangled appropriately. Below is the source of
the demangle script:
#!/home/andrei/bin/rdmd
import std.algorithm, std.demangle, std.getopt, std.stdio;
void main(string[] args)
{
string lSep = "`", rSep = "'";
getopt(args, "lsep", &lSep, "rsep", &rSep);
foreach (line; stdin.byLine())
{
auto sym = find(line, lSep);
if (!sym.length)
{
writeln(line);
continue;
}
sym = sym[1 .. $];
auto before = line[0 .. $ - sym.length];
sym = sym[0 .. $ - find(sym, rSep).length];
auto after = line[before.length + sym.length .. $];
writeln(before, demangle(sym.idup), after);
}
}
Hope this helps someone,
Andrei
Apr 09 2009
I wrote something like that, like what, years ago? Debugging D programs with the current toolchain is a serious pain in the ass, but a demangler makes it a bit more tolerable. By the way, is the current std.demangle functionally complete?
Apr 09 2009
grauzone wrote:I wrote something like that, like what, years ago? Debugging D programs with the current toolchain is a serious pain in the ass, but a demangler makes it a bit more tolerable. By the way, is the current std.demangle functionally complete?
No idea. Andrei
Apr 09 2009
grauzone, el 9 de abril a las 23:33 me escribiste:I wrote something like that, like what, years ago? Debugging D programs with the current toolchain is a serious pain in the ass, but a demangler makes it a bit more tolerable. By the way, is the current std.demangle functionally complete?
There is even an example program that does this in the std.demangle module documentation[1], even for D2[2] ;) Maybe the D2 example can be changed for this program, that is more D2-ish. [1] http://www.digitalmars.com/d/1.0/phobos/std_demangle.html [2] http://www.digitalmars.com/d/2.0/phobos/std_demangle.html -- Leandro Lucarella (luca) | Blog colectivo: http://www.mazziblog.com.ar/blog/ ---------------------------------------------------------------------------- GPG Key: 5F5A8D05 (F8CD F9A7 BF00 5431 4145 104C 949E BFB6 5F5A 8D05) ---------------------------------------------------------------------------- There is no pain you are receding A distant ship, smoke on the horizon. You are only coming through in waves. Your lips move but I can't hear what you're saying.
Apr 09 2009
Hurm. I thought one of the things D had over C++ was that with aliases such complex error messages can be avoided. While D still seems to be better off than C++ I guess something like this is unavoidable with metaprogramming? Andrei Alexandrescu Wrote:I wrote a simple utility (at the bottom of this message) that may help debugging link-time errors. It reads lines from stdin and writes them with DMD symbols, if any, demangled. For example, here's what you see if you add "alias field this;" to Tuple in std.typecons and try to build the "new, new" Phobos: obj/posix/debug/unittest/std/file.o: In function `_D3std4file14__T5slurpTiTdZ5slurpFAyaxAaZAS3std8typecons14__T5TupleTiTdZ5Tuple': /home/andrei/code/dmd/phobos/std/file.d:1772: undefined reference to `_D3std8typecons14__T5TupleTiTdZ5Tuple6__initZ' /home/andrei/code/dmd/phobos/std/file.d:1781: undefined reference to `_D3std5array51__T8AppenderTAS3std8typecons14__T5TupleTiTdZ5TupleZ8Appender3putMFxS3std8typecons14__T5TupleTiTdZ5TupleZv' obj/posix/debug/unittest/std/file.o: In function `_D3std5array88__T8appenderTAS3std8typecons14__T5TupleTiTdZ5TupleTS3std8typecons14__T5TupleTiTdZ5TupleZ8appenderFPAS3std8typecons14__T5TupleTiTdZ5TupleZS3std5array51__T8AppenderTAS3std8typecons14__T5TupleTiTdZ5TupleZ8Appender': /home/andrei/code/dmd/phobos/std/array.d:578: undefined reference to `_D3std5array51__T8AppenderTAS3std8typecons14__T5TupleTiTdZ5TupleZ8Appender6__ctorMFNcPAS3std8typecons14__T5TupleTiTdZ5TupleZS3std5array51__T8AppenderTAS3std8typecons14__T5TupleTiTdZ5TupleZ8Appender' obj/posix/debug/unittest/std/file.o: In function `_D3std8typecons14__T5tupleTiTdZ5tupleFidZS3std8typecons14__T5TupleTiTdZ5Tuple': /home/andrei/code/dmd/phobos/std/typecons.d:515: undefined reference to `_D3std8typecons14__T5TupleTiTdZ5Tuple6__initZ' collect2: ld returned 1 exit status --- errorlevel 1 However, if you use "make |& ./demangle.d", you see: obj/posix/debug/unittest/std/file.o: In function `struct std.typecons.Tuple!(int, double).Tuple[] std.file.slurp!(int, double).slurp(immutable(char)[], const(char[]))': /home/andrei/code/dmd/phobos/std/file.d:1772: undefined reference to `Z std.typecons.Tuple!(int, double).Tuple.__init' /home/andrei/code/dmd/phobos/std/file.d:1781: undefined reference to `void std.array.Appender!(struct std.typecons.Tuple!(int, double).Tuple[]).Appender.put(const(struct std.typecons.Tuple!(int, double).Tuple))' obj/posix/debug/unittest/std/file.o: In function `struct std.array.Appender!(struct std.typecons.Tuple!(int, double).Tuple[]).Appender std.array.appender!(struct std.typecons.Tuple!(int, double).Tuple[], struct std.typecons.Tuple!(int, double).Tuple).appender(struct std.typecons.Tuple!(int, double).Tuple[]*)': /home/andrei/code/dmd/phobos/std/array.d:578: undefined reference to `_D3std5array51__T8AppenderTAS3std8typecons14__T5TupleTiTdZ5TupleZ8Appender6__ctorMFNcPAS3std8typecons14__T5TupleTiTdZ5TupleZS3std5array51__T8AppenderTAS3std8typecons14__T5TupleTiTdZ5TupleZ8Appender' obj/posix/debug/unittest/std/file.o: In function `struct std.typecons.Tuple!(int, double).Tuple std.typecons.tuple!(int, double).tuple(int, double)': /home/andrei/code/dmd/phobos/std/typecons.d:515: undefined reference to `Z std.typecons.Tuple!(int, double).Tuple.__init' collect2: ld returned 1 exit status --- errorlevel 1 make: *** [obj/posix/debug/unittest/std/file] Error 1 The line wraps are all garbled, but you get the idea: all symbols quoted `like this' have been demangled appropriately. Below is the source of the demangle script: #!/home/andrei/bin/rdmd import std.algorithm, std.demangle, std.getopt, std.stdio; void main(string[] args) { string lSep = "`", rSep = "'"; getopt(args, "lsep", &lSep, "rsep", &rSep); foreach (line; stdin.byLine()) { auto sym = find(line, lSep); if (!sym.length) { writeln(line); continue; } sym = sym[1 .. $]; auto before = line[0 .. $ - sym.length]; sym = sym[0 .. $ - find(sym, rSep).length]; auto after = line[before.length + sym.length .. $]; writeln(before, demangle(sym.idup), after); } } Hope this helps someone, Andrei
Apr 10 2009
R:While D still seems to be better off than C++ I guess something like this is unavoidable with metaprogramming?<
Lot of people have discussed about this topic, and some of them have even found some partial solutions, for example: http://www.ddj.com/cpp/184401416?pgno=1 Of course Andrei was among them :-) Some of those ideas can be implemented in a native way into the D compiler. Bye, bearophile
Apr 10 2009
Thu, 09 Apr 2009 13:40:36 -0700, Andrei Alexandrescu wrote:The line wraps are all garbled, but you get the idea: all symbols quoted `like this' have been demangled appropriately. Below is the source of the demangle script: #!/home/andrei/bin/rdmd import std.algorithm, std.demangle, std.getopt, std.stdio; void main(string[] args) { string lSep = "`", rSep = "'"; getopt(args, "lsep", &lSep, "rsep", &rSep); foreach (line; stdin.byLine()) { auto sym = find(line, lSep); if (!sym.length) { writeln(line); continue; } sym = sym[1 .. $]; auto before = line[0 .. $ - sym.length]; sym = sym[0 .. $ - find(sym, rSep).length]; auto after = line[before.length + sym.length .. $]; writeln(before, demangle(sym.idup), after); } }
What happened to the range boolean operations, those before/after/whatever? Do you still plan to implement them?
Apr 10 2009
Sergey Gromov wrote:Thu, 09 Apr 2009 13:40:36 -0700, Andrei Alexandrescu wrote:The line wraps are all garbled, but you get the idea: all symbols quoted `like this' have been demangled appropriately. Below is the source of the demangle script: #!/home/andrei/bin/rdmd import std.algorithm, std.demangle, std.getopt, std.stdio; void main(string[] args) { string lSep = "`", rSep = "'"; getopt(args, "lsep", &lSep, "rsep", &rSep); foreach (line; stdin.byLine()) { auto sym = find(line, lSep); if (!sym.length) { writeln(line); continue; } sym = sym[1 .. $]; auto before = line[0 .. $ - sym.length]; sym = sym[0 .. $ - find(sym, rSep).length]; auto after = line[before.length + sym.length .. $]; writeln(before, demangle(sym.idup), after); } }
What happened to the range boolean operations, those before/after/whatever? Do you still plan to implement them?
Curiously, I didn't find a need for them in std.algorithm so far. I only defined sameHead, and that's only to help a little improvement in the bringToFront algorithm. Andrei
Apr 10 2009
On 2009-04-10 17:25:30 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Curiously, I didn't find a need for them in std.algorithm so far. I only defined sameHead, and that's only to help a little improvement in the bringToFront algorithm.
I've written a few parsers where I repeat this pattern a lot: string read(alias consumer)(ref string input) { string value = input; consumer(input); return value.before(input); } And I like very much how it reads: "text before input". All this done on D1. Perhaps it'd need to be revamped a little for D2. Here's my implementation if you're interested. T[] after(T)(T[] r, T[] s) in { assert(s.ptr >= r.ptr && s.ptr <= r.ptr + r.length); } body { char* begin = s.ptr + s.length; char* end = r.ptr + r.length; return begin[0..end-begin]; } T[] before(T)(T[] r, T[] s) in { assert(s.ptr >= r.ptr && s.ptr <= r.ptr + r.length); } body { char* begin = r.ptr; char* end = s.ptr; return begin[0..end-begin]; } unittest { string a = "abcdef"; string b = a[1..3]; // bc assert(a.after(b) == "def"); assert(a.before(b) == "a"); string c = a[3..3]; // empty string assert(a.after(c) == "def"); assert(a.before(c) == "abc"); string d = a[0..$]; // same string assert(a.after(d) == ""); assert(a.before(d) == ""); } -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 10 2009
Michel Fortin wrote:On 2009-04-10 17:25:30 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Curiously, I didn't find a need for them in std.algorithm so far. I only defined sameHead, and that's only to help a little improvement in the bringToFront algorithm.
I've written a few parsers where I repeat this pattern a lot: string read(alias consumer)(ref string input) { string value = input; consumer(input); return value.before(input); } And I like very much how it reads: "text before input". All this done on D1. Perhaps it'd need to be revamped a little for D2. Here's my implementation if you're interested.
Thanks. Arrays aren't a problem, but non-random-access ranges are problematic. (For arrays a slice could also be taken.) That's why I've been reluctant - if I make before and after primitives, then anyone defining a range needs to worry about implementing them. Andrei
Apr 10 2009
On 2009-04-11 00:00:08 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Thanks. Arrays aren't a problem, but non-random-access ranges are problematic. (For arrays a slice could also be taken.) That's why I've been reluctant - if I make before and after primitives, then anyone defining a range needs to worry about implementing them.
Then could it be limited to random-access ranges? Other ranges could provide their own implementation, if it makes sense for them. That'd make another category of ranges: "intersectable ranges". We could just provide primitives for consuming a range and returning the consumed data (as my read function does above). This could be supported by all ranges. Which makes me think: how does the new regex library handle consuming and backtracking with ranges? -- Michel Fortin michel.fortin michelf.com http://michelf.com/
Apr 11 2009
Michel Fortin wrote:On 2009-04-11 00:00:08 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> said:Thanks. Arrays aren't a problem, but non-random-access ranges are problematic. (For arrays a slice could also be taken.) That's why I've been reluctant - if I make before and after primitives, then anyone defining a range needs to worry about implementing them.
Then could it be limited to random-access ranges? Other ranges could provide their own implementation, if it makes sense for them. That'd make another category of ranges: "intersectable ranges". We could just provide primitives for consuming a range and returning the consumed data (as my read function does above). This could be supported by all ranges. Which makes me think: how does the new regex library handle consuming and backtracking with ranges?
For now regex only supports random-access ranges. Andrei
Apr 11 2009
Fri, 10 Apr 2009 14:25:30 -0700, Andrei Alexandrescu wrote:Sergey Gromov wrote:Thu, 09 Apr 2009 13:40:36 -0700, Andrei Alexandrescu wrote:The line wraps are all garbled, but you get the idea: all symbols quoted `like this' have been demangled appropriately. Below is the source of the demangle script: #!/home/andrei/bin/rdmd import std.algorithm, std.demangle, std.getopt, std.stdio; void main(string[] args) { string lSep = "`", rSep = "'"; getopt(args, "lsep", &lSep, "rsep", &rSep); foreach (line; stdin.byLine()) { auto sym = find(line, lSep); if (!sym.length) { writeln(line); continue; } sym = sym[1 .. $]; auto before = line[0 .. $ - sym.length]; sym = sym[0 .. $ - find(sym, rSep).length]; auto after = line[before.length + sym.length .. $]; writeln(before, demangle(sym.idup), after); } }
What happened to the range boolean operations, those before/after/whatever? Do you still plan to implement them?
Curiously, I didn't find a need for them in std.algorithm so far. I only defined sameHead, and that's only to help a little improvement in the bringToFront algorithm.
I asked because I thought that "blah[foo.length .. $ - bar.length]" stuff wasn't very nice. Compare: sym.advance; // popFront, or sym[1 .. $] auto s1 = line.before(sym); auto s3 = find(sym, rSep); writeln(s1, demangle(sym.before(s3).idup), s3);
Apr 12 2009
It looks useful, especially when using rdmd. Why does rdmd require that the file end in .d? That seems limiting, especially when I want to make an executable file that looks like other executables in linux... aka no extension at all. Andrei Alexandrescu wrote:I wrote a simple utility (at the bottom of this message) that may help debugging link-time errors. It reads lines from stdin and writes them with DMD symbols, if any, demangled.
Apr 10 2009
Jason House wrote:It looks useful, especially when using rdmd. Why does rdmd require that the file end in .d? That seems limiting, especially when I want to make an executable file that looks like other executables in linux... aka no extension at all. Andrei Alexandrescu wrote:I wrote a simple utility (at the bottom of this message) that may help debugging link-time errors. It reads lines from stdin and writes them with DMD symbols, if any, demangled.
Good point. Also zsh-style streams <(...) could be supported. Any chance you could take a minute to submit a bug report? I'll take care of it when I have time. Andrei
Apr 10 2009









Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> 