 <blockquote> <p>I am unable to find a convincing answer as to why the information from the -g option is insufficient for de-compilation, but sufficient for debugging?</p> </blockquote> <p>The debugging information basically contains only mapping between the addresses in the generated code and the source files line numbers. The debugger does not need to decompile code - it just shows you the original sources. If the source files are missing, debugger won't magically show them.</p> <p>That said, presence of debugging info does make decompilation easier. If the debug info includes the layout of the used types and function prototypes, the decompiler can use it and provide a much more precise decompilation. In many cases, however, it will still likely be different from the original source.</p> <p>For example, here's a function decompiled with the Hex-Rays decompiler without using the debug info:</p> <pre><code>int __stdcall sub_4050A0(int a1) { int result; // eax@1 result = a1; if ( *(_BYTE *)(a1 + 12) ) { result = sub_404600(*(_DWORD *)a1); *(_BYTE *)(a1 + 12) = 0; } return result; } </code></pre> <p>Since it does not know the type of <code>a1</code>, the accesses to its fields are represented as additions and casts.</p> <p>And here's the same function after the symbol file has been loaded:</p> <pre><code>void __thiscall mytree::write_page(mytree *this, PAGE *src) { if ( src-&gt;isChanged ) { cache::set_changed(this-&gt;cache, src-&gt;baseAddr); src-&gt;isChanged = 0; } } </code></pre> <p>You can see that it's been improved quite a lot.</p> <p>As for why decompiling bytecode is usually easier, in addition to NPE's answer check also <a href="http://stackoverflow.com/a/5160714/422797">this</a>.</p>