mirror of git://gcc.gnu.org/git/gcc.git
Add dot-fn to gdbhooks.py
2016-02-22 Richard Biener <rguenther@suse.de> Tom de Vries <tom@codesourcery.com> * graph.c: Include dumpfile.h. (print_graph_cfg): Split into three overloads. * gdbhooks.py (class DotFn): Add and instantiate, adding command dot-fn. Co-Authored-By: Tom de Vries <tom@codesourcery.com> From-SVN: r233600
This commit is contained in:
parent
b6e5b400c3
commit
bddb7adb44
|
|
@ -1,3 +1,10 @@
|
|||
2016-02-22 Richard Biener <rguenther@suse.de>
|
||||
Tom de Vries <tom@codesourcery.com>
|
||||
|
||||
* graph.c: Include dumpfile.h.
|
||||
(print_graph_cfg): Split into three overloads.
|
||||
* gdbhooks.py (class DotFn): Add and instantiate, adding command dot-fn.
|
||||
|
||||
2016-02-22 Tom de Vries <tom@codesourcery.com>
|
||||
|
||||
* gdbhooks.py (class DumpFn): Add and instantiate, adding command
|
||||
|
|
|
|||
|
|
@ -680,4 +680,74 @@ class DumpFn(gdb.Command):
|
|||
|
||||
DumpFn()
|
||||
|
||||
class DotFn(gdb.Command):
|
||||
"""
|
||||
A custom command to show a gimple/rtl function control flow graph.
|
||||
By default, it show the current function, but the function can also be
|
||||
specified.
|
||||
|
||||
Examples of use:
|
||||
(gdb) dot-fn
|
||||
(gdb) dot-fn cfun
|
||||
(gdb) dot-fn cfun 0
|
||||
(gdb) dot-fn cfun dump_flags
|
||||
"""
|
||||
def __init__(self):
|
||||
gdb.Command.__init__(self, 'dot-fn', gdb.COMMAND_USER)
|
||||
|
||||
def invoke(self, arg, from_tty):
|
||||
# Parse args, check number of args
|
||||
args = gdb.string_to_argv(arg)
|
||||
if len(args) > 2:
|
||||
print("Too many arguments")
|
||||
return
|
||||
|
||||
# Set func
|
||||
if len(args) >= 1:
|
||||
funcname = args[0]
|
||||
printfuncname = "function %s" % funcname
|
||||
else:
|
||||
funcname = "cfun"
|
||||
printfuncname = "current function"
|
||||
func = gdb.parse_and_eval(funcname)
|
||||
if func == 0:
|
||||
print("Could not find %s" % printfuncname)
|
||||
return
|
||||
func = "(struct function *)%s" % func
|
||||
|
||||
# Set flags
|
||||
if len(args) >= 2:
|
||||
flags = gdb.parse_and_eval(args[1])
|
||||
else:
|
||||
flags = 0
|
||||
|
||||
# Get temp file
|
||||
f = tempfile.NamedTemporaryFile(delete=False)
|
||||
filename = f.name
|
||||
|
||||
# Close and reopen temp file to get C FILE*
|
||||
f.close()
|
||||
fp = gdb.parse_and_eval("fopen (\"%s\", \"w\")" % filename)
|
||||
if fp == 0:
|
||||
print("Cannot open temp file")
|
||||
return
|
||||
fp = "(FILE *)%u" % fp
|
||||
|
||||
# Write graph to temp file
|
||||
_ = gdb.parse_and_eval("start_graph_dump (%s, \"<debug>\")" % fp)
|
||||
_ = gdb.parse_and_eval("print_graph_cfg (%s, %s, %u)"
|
||||
% (fp, func, flags))
|
||||
_ = gdb.parse_and_eval("end_graph_dump (%s)" % fp)
|
||||
|
||||
# Close temp file
|
||||
ret = gdb.parse_and_eval("fclose (%s)" % fp)
|
||||
if ret != 0:
|
||||
print("Could not close temp file: %s" % filename)
|
||||
return
|
||||
|
||||
# Show graph in temp file
|
||||
os.system("( dot -Tx11 \"%s\"; rm \"%s\" ) &" % (filename, filename))
|
||||
|
||||
DotFn()
|
||||
|
||||
print('Successfully loaded GDB hooks for GCC')
|
||||
|
|
|
|||
32
gcc/graph.c
32
gcc/graph.c
|
|
@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
|
|||
#include "cfganal.h"
|
||||
#include "cfgloop.h"
|
||||
#include "graph.h"
|
||||
#include "dumpfile.h"
|
||||
|
||||
/* DOT files with the .dot extension are recognized as document templates
|
||||
by a well-known piece of word processing software out of Redmond, WA.
|
||||
|
|
@ -272,14 +273,13 @@ draw_cfg_edges (pretty_printer *pp, struct function *fun)
|
|||
subgraphs right for GraphViz, which requires nodes to be defined
|
||||
before edges to cluster nodes properly. */
|
||||
|
||||
void
|
||||
print_graph_cfg (const char *base, struct function *fun)
|
||||
void DEBUG_FUNCTION
|
||||
print_graph_cfg (FILE *fp, struct function *fun)
|
||||
{
|
||||
const char *funcname = function_name (fun);
|
||||
FILE *fp = open_graph_file (base, "a");
|
||||
pretty_printer graph_slim_pp;
|
||||
graph_slim_pp.buffer->stream = fp;
|
||||
pretty_printer *const pp = &graph_slim_pp;
|
||||
const char *funcname = function_name (fun);
|
||||
pp_printf (pp, "subgraph \"cluster_%s\" {\n"
|
||||
"\tstyle=\"dashed\";\n"
|
||||
"\tcolor=\"black\";\n"
|
||||
|
|
@ -289,6 +289,30 @@ print_graph_cfg (const char *base, struct function *fun)
|
|||
draw_cfg_edges (pp, fun);
|
||||
pp_printf (pp, "}\n");
|
||||
pp_flush (pp);
|
||||
}
|
||||
|
||||
/* Overload with additional flag argument. */
|
||||
|
||||
void DEBUG_FUNCTION
|
||||
print_graph_cfg (FILE *fp, struct function *fun, int flags)
|
||||
{
|
||||
int saved_dump_flags = dump_flags;
|
||||
dump_flags = flags;
|
||||
print_graph_cfg (fp, fun);
|
||||
dump_flags = saved_dump_flags;
|
||||
}
|
||||
|
||||
|
||||
/* Print a graphical representation of the CFG of function FUN.
|
||||
First print all basic blocks. Draw all edges at the end to get
|
||||
subgraphs right for GraphViz, which requires nodes to be defined
|
||||
before edges to cluster nodes properly. */
|
||||
|
||||
void
|
||||
print_graph_cfg (const char *base, struct function *fun)
|
||||
{
|
||||
FILE *fp = open_graph_file (base, "a");
|
||||
print_graph_cfg (fp, fun);
|
||||
fclose (fp);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue