diff options
author | Tom Tromey <tromey@redhat.com> | 2014-06-15 21:28:57 -0600 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2014-07-24 07:39:47 -0600 |
commit | a7068b601288f8f5df45ca1113069b44dc759b11 (patch) | |
tree | e7f627f17e4d98f06b82138a3a57b356da148da9 /gdb/make-target-delegates | |
parent | 2c51604d3adbcc77a25d78ce900f5be4597c2504 (diff) | |
download | gdb-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-x | gdb/make-target-delegates | 88 |
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"; |