• He Kuang's avatar
    perf probe: Add --range option to show a variable's location range · 349e8d26
    He Kuang authored
    It is not easy for users to get the accurate byte offset or the line
    number where a local variable can be probed.
    
    With '--range' option, local variables in the scope of the probe point
    are showed with a byte offset range, and can be added according to this
    range information.
    
    For example, there are some variables in the function
    generic_perform_write():
    
      <generic_perform_write@mm/filemap.c:0>
      0  ssize_t generic_perform_write(struct file *file,
      1                                 struct iov_iter *i, loff_t pos)
      2  {
      3          struct address_space *mapping = file->f_mapping;
      4          const struct address_space_operations *a_ops = mapping->a_ops;
      ...
      42                 status = a_ops->write_begin(file, mapping, pos, bytes, flags,
                                                   &page, &fsdata);
      44                 if (unlikely(status < 0))
    
    But we fail when we try to probe the variable 'a_ops' at line 42 or 44.
    
      $ perf probe --add 'generic_perform_write:42 a_ops'
      Failed to find the location of a_ops at this address.
        Perhaps, it has been optimized out.
    
    This is because the source code do not match the assembly, so a variable
    may not be available in the source code line where it appears.
    
    After this patch, we can lookup the accurate byte offset range of a
    variable, 'INV' indicates that this variable is not valid at the given
    point, but available in the scope:
    
      $ perf probe --vars 'generic_perform_write:42' --range
      Available variables at generic_perform_write:42
        @<generic_perform_write+141>
           [INV] ssize_t written @<generic_perform_write+[324-331]>
           [INV] struct address_space_operations*        a_ops   @<generic_perform_write+[55-61,170-176,223-246]>
           [VAL] (unknown_type)  fsdata  @<generic_perform_write+[70-307,346-411]>
           [VAL] loff_t  pos     @<generic_perform_write+[0-286,286-336,346-411]>
           [VAL] long int        status  @<generic_perform_write+[83-342,346-411]>
           [VAL] long unsigned int       bytes   @<generic_perform_write+[122-311,320-338,346-403,403-411]>
           [VAL] struct address_space*   mapping @<generic_perform_write+[35-344,346-411]>
           [VAL] struct iov_iter*        i       @<generic_perform_write+[0-340,346-411]>
           [VAL] struct page*    page    @<generic_perform_write+[70-307,346-411]>
    
    Then it is more clear for us to add a probe with this variable:
    
      $ perf probe --add 'generic_perform_write+170 a_ops'
      Added new event:
        probe:generic_perform_write (on generic_perform_write+170 with a_ops)
    Signed-off-by: default avatarHe Kuang <hekuang@huawei.com>
    Acked-by: default avatarMasami Hiramatsu <masami.hiramatsu.pt@hitachi.com>
    Cc: Jiri Olsa <jolsa@kernel.org>
    Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
    Cc: Wang Nan <wangnan0@huawei.com>
    Link: http://lkml.kernel.org/r/1431336304-16863-2-git-send-email-hekuang@huawei.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
    349e8d26
builtin-probe.c 13.5 KB