aboutsummaryrefslogtreecommitdiff
path: root/gdb/make-target-delegates
diff options
context:
space:
mode:
authorTom Tromey <tromey@redhat.com>2014-06-15 21:28:57 -0600
committerTom Tromey <tromey@redhat.com>2014-07-24 07:39:47 -0600
commita7068b601288f8f5df45ca1113069b44dc759b11 (patch)
treee7f627f17e4d98f06b82138a3a57b356da148da9 /gdb/make-target-delegates
parent2c51604d3adbcc77a25d78ce900f5be4597c2504 (diff)
downloadgdb-a7068b601288f8f5df45ca1113069b44dc759b11.zip
gdb-a7068b601288f8f5df45ca1113069b44dc759b11.tar.gz
gdb-a7068b601288f8f5df45ca1113069b44dc759b11.tar.bz2
auto-generate most target debug methods
The target debug methods are inconsistently maintained. Most to_* methods have some kind of targetdebug awareness, but not all of them do. The ones that do vary in the quantity and quality of output they generate. This patch changes most of the target debug methods to be automatically generated. All the arguments are printed, and separate lines are printed for entering and existing the outermost call to the target stack. For example now you'd see: -> multi-thread->to_terminal_ours (...) -> multi-thread->to_is_async_p (...) <- multi-thread->to_is_async_p (0x1ebb580) = 1 <- multi-thread->to_terminal_ours (0x1ebb580) -> multi-thread->to_thread_address_space (...) <- multi-thread->to_thread_address_space (0x1ebb580, 26802) = 1 In this case you can see nested calls. The "multi-thread" on the left hand side is the topmost target's shortname. There are some oddities with this patch. I'm on the fence about it all, I really just wrote it on a whim. It's not simple to convert every possible method, since a few don't participate in target delegation. Printing is done by type, so I introduced some new debug-printing-specific typedefs to handle cases where it is nicer to do something else. On the plus side, this lays the groundwork for making targetdebug affect every layer of the target stack. The idea would be to wrap each target_ops in the stack with its own debug_target, and then you could see calls propagate down the stack and back up; I suppose with indentation to make it prettier. (That said there are some gotchas lurking in this idea due to target stack introspection.) Regtested on x86-64 Fedora 20. 2014-07-24 Tom Tromey <tromey@redhat.com> * make-target-delegates (munge_type, write_debugmethod): New functions. (debug_names): New global. ($TARGET_DEBUG_PRINTER): New global. (write_function_header): Strip TARGET_DEBUG_PRINTER from the type name. Write debug methods. Generate init_debug_target. * target-debug.h: New file. * target-delegates.c: Rebuild. * target.c: Include target-debug.h. (debug_target): Hoist definition. (target_kill, target_get_section_table, target_memory_map) (target_flash_erase, target_flash_done, target_detach) (target_disconnect, target_wait, target_resume) (target_pass_signals, target_program_signals, target_follow_fork) (target_mourn_inferior, target_search_memory) (target_thread_address_space, target_close) (target_find_new_threads, target_core_of_thread) (target_verify_memory, target_insert_mask_watchpoint) (target_remove_mask_watchpoint): Remove targetdebug code. (debug_to_post_attach, debug_to_prepare_to_store) (debug_to_files_info, debug_to_insert_breakpoint) (debug_to_remove_breakpoint, debug_to_can_use_hw_breakpoint) (debug_to_region_ok_for_hw_watchpoint) (debug_to_can_accel_watchpoint_condition) (debug_to_stopped_by_watchpoint, debug_to_stopped_data_address) (debug_to_watchpoint_addr_within_range) (debug_to_insert_hw_breakpoint, debug_to_remove_hw_breakpoint) (debug_to_insert_watchpoint, debug_to_remove_watchpoint) (debug_to_terminal_init, debug_to_terminal_inferior) (debug_to_terminal_ours_for_output, debug_to_terminal_ours) (debug_to_terminal_save_ours, debug_to_terminal_info) (debug_to_load, debug_to_post_startup_inferior) (debug_to_insert_fork_catchpoint) (debug_to_remove_fork_catchpoint) (debug_to_insert_vfork_catchpoint) (debug_to_remove_vfork_catchpoint) (debug_to_insert_exec_catchpoint) (debug_to_remove_exec_catchpoint, debug_to_has_exited) (debug_to_can_run, debug_to_thread_architecture, debug_to_stop) (debug_to_rcmd, debug_to_pid_to_exec_file): Remove. (setup_target_debug): Call init_debug_target. * target.h (TARGET_DEBUG_PRINTER): New macro. (struct target_ops) <to_resume, to_wait, to_pass_signals, to_program_signals>: Use TARGET_DEBUG_PRINTER.
Diffstat (limited to 'gdb/make-target-delegates')
-rwxr-xr-xgdb/make-target-delegates88
1 files changed, 88 insertions, 0 deletions
diff --git a/gdb/make-target-delegates b/gdb/make-target-delegates
index 28db447..085c8bc 100755
--- a/gdb/make-target-delegates
+++ b/gdb/make-target-delegates
@@ -54,6 +54,11 @@ $METHOD = ($INTRO_PART . "(?<return_type>" . $SIMPLE_RETURN_PART
. $NAME_PART . $ARGS_PART
. $METHOD_TRAILER);
+# Match TARGET_DEBUG_PRINTER in an argument type.
+# This must match the whole "sub-expression" including the parens.
+# Reference $1 must refer to the function argument.
+$TARGET_DEBUG_PRINTER = qr,\s*TARGET_DEBUG_PRINTER\s*\(([^)]*)\)\s*,;
+
sub trim($) {
my ($result) = @_;
@@ -144,6 +149,8 @@ sub write_function_header($$@) {
foreach $iter (@argtypes) {
my $val = $iter;
+ $val =~ s/$TARGET_DEBUG_PRINTER//;
+
if ($iter !~ m,\*$,) {
$val .= ' ';
}
@@ -217,6 +224,75 @@ sub write_tdefault($$$$@) {
return tdname ($name);
}
+sub munge_type($) {
+ my ($typename) = @_;
+ my ($result);
+
+ if ($typename =~ m/$TARGET_DEBUG_PRINTER/) {
+ $result = $1;
+ } else {
+ ($result = $typename) =~ s/\s+$//;
+ $result =~ s/[ ()]/_/g;
+ $result =~ s/[*]/p/g;
+ $result = 'target_debug_print_' . $result;
+ }
+
+ return $result;
+}
+
+# Write out a debug method.
+sub write_debugmethod($$$$@) {
+ my ($content, $style, $name, $return_type, @argtypes) = @_;
+
+ my ($debugname) = $name;
+ $debugname =~ s/to_/debug_/;
+ my ($targetname) = $name;
+ $targetname =~ s/to_/target_/;
+
+ my (@names) = write_function_header ($debugname, $return_type, @argtypes);
+
+ if ($return_type ne 'void') {
+ print " $return_type result;\n";
+ }
+
+ print " fprintf_unfiltered (gdb_stdlog, \"-> %s->$name (...)\\n\", debug_target.to_shortname);\n";
+
+ # Delegate to the beneath target.
+ print " ";
+ if ($return_type ne 'void') {
+ print "result = ";
+ }
+ print "debug_target." . $name . " (";
+ my @names2 = @names;
+ @names2[0] = "&debug_target";
+ print join (', ', @names2);
+ print ");\n";
+
+ # Now print the arguments.
+ print " fprintf_unfiltered (gdb_stdlog, \"<- %s->$name (\", debug_target.to_shortname);\n";
+ for my $i (0 .. $#argtypes) {
+ print " fputs_unfiltered (\", \", gdb_stdlog);\n" if $i > 0;
+ my $printer = munge_type ($argtypes[$i]);
+ print " $printer ($names2[$i]);\n";
+ }
+ if ($return_type ne 'void') {
+ print " fputs_unfiltered (\") = \", gdb_stdlog);\n";
+ my $printer = munge_type ($return_type);
+ print " $printer (result);\n";
+ print " fputs_unfiltered (\"\\n\", gdb_stdlog);\n";
+ } else {
+ print " fputs_unfiltered (\")\\n\", gdb_stdlog);\n";
+ }
+
+ if ($return_type ne 'void') {
+ print " return result;\n";
+ }
+
+ print "}\n\n";
+
+ return $debugname;
+}
+
print "/* THIS FILE IS GENERATED -*- buffer-read-only: t -*- */\n";
print "/* vi:set ro: */\n\n";
print "/* To regenerate this file, run:*/\n";
@@ -226,6 +302,7 @@ print "/* make-target-delegates target.h > target-delegates.c */\n";
%tdefault_names = ();
+%debug_names = ();
@delegators = ();
foreach $current_line (@lines) {
next unless $current_line =~ m/$METHOD/;
@@ -248,6 +325,10 @@ foreach $current_line (@lines) {
$tdefault_names{$name} = write_tdefault ($tdefault, $style,
$name, $return_type,
@argtypes);
+
+ $debug_names{$name} = write_debugmethod ($tdefault, $style,
+ $name, $return_type,
+ @argtypes);
}
}
@@ -266,4 +347,11 @@ print "static void\ninstall_dummy_methods (struct target_ops *ops)\n{\n";
for $iter (@delegators) {
print " ops->" . $iter . " = " . $tdefault_names{$iter} . ";\n";
}
+print "}\n\n";
+
+# The debug method code.
+print "static void\ninit_debug_target (struct target_ops *ops)\n{\n";
+for $iter (@delegators) {
+ print " ops->" . $iter . " = " . $debug_names{$iter} . ";\n";
+}
print "}\n";