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:
Richard Biener 2016-02-22 10:31:41 +00:00 committed by Tom de Vries
parent b6e5b400c3
commit bddb7adb44
3 changed files with 105 additions and 4 deletions

View File

@ -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

View File

@ -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')

View File

@ -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);
}