From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 16942 invoked by alias); 28 Jan 2014 21:00:07 -0000 Mailing-List: contact systemtap-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: systemtap-owner@sourceware.org Received: (qmail 16868 invoked by uid 48); 28 Jan 2014 21:00:02 -0000 From: "jlebon at redhat dot com" To: systemtap@sourceware.org Subject: [Bug translator/1133] support .callees probe pattern extension Date: Tue, 28 Jan 2014 21:00:00 -0000 X-Bugzilla-Reason: AssignedTo X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: systemtap X-Bugzilla-Component: translator X-Bugzilla-Version: unspecified X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: jlebon at redhat dot com X-Bugzilla-Status: ASSIGNED X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: systemtap at sourceware dot org X-Bugzilla-Target-Milestone: week X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 7bit X-Bugzilla-URL: http://sourceware.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-SW-Source: 2014-q1/txt/msg00066.txt.bz2 https://sourceware.org/bugzilla/show_bug.cgi?id=1133 --- Comment #5 from Jonathan Lebon --- (In reply to Jonathan Lebon from comment #4) > What the new DW_TAG_call_site DIE does give us however is a way of listing > callees of a DW_TAG_subprogram. So, we could use them to support > .callees("") by retrieving the address from the DIEs of all target functions. I've implemented this feature on my branch jlebon/callee. I've opted for the '.callee' suffix instead of callees to be more in line with other components that allow a string arg to filter results, such as 'function', 'label', etc... If desired, we can also add a .callees as a shorthand for .callee("*"). The branch also includes a 'temp' dir with some sample programs on which to test it. For example: $ cd temp $ cat simple.c // gcc -o simple simple.c -g -O __attribute__((noinline)) int func(int a, int b) { return a + b; } int main(void) { int a = 1; a = func(a, a); return a; } $ gcc -o simple simple.c -g -O $ stap -L 'process("simple").function("main").callee("*")' process("/home/yyz/jlebon/codebase/systemtap/systemtap/temp/simple").function("func@/home/yyz/jlebon/codebase/systemtap/systemtap/temp/simple.c:4") $a:int $b:int $ $ $ $ cat inlined.c // gcc -o inlined inlined.c -g -O __attribute__((noinline)) int foo(int a, int b) { return a % b; } __attribute__((always_inline)) int func(int a, int b) { int c, d, e; c = a + b; d = a * b; e = foo(c, d); return e - 1; } int main(void) { int a = 1; a = func(a, a); return a; } $ gcc -o inlined inlined.c -g -O -w $ stap -L 'process("inlined").function("main").callee("*")' process("/home/yyz/jlebon/codebase/systemtap/systemtap/temp/inlined").function("func@/home/yyz/jlebon/codebase/systemtap/systemtap/temp/inlined.c:9") $b:int $a:int $ stap -L 'process("inlined").function("func").callee("*")' process("/home/yyz/jlebon/codebase/systemtap/systemtap/temp/inlined").function("foo@/home/yyz/jlebon/codebase/systemtap/systemtap/temp/inlined.c:4") $a:int $b:int $ Callee functions defined externally are also supported: $ cat extern.c // gcc -o extern extern.c extern2.c -g -O long int fn2 (long int, long int, long int); long int fn4 (long int *i, long int j); long int fn3 (long int x, long int (*fn4) (long int *, long int)) { long int v, w, w2, z; w = (*fn4) (&w2, x); v = (*fn4) (&w2, x); z = fn2 (1, v + 1, w); { int v1 = v + 4; z += fn2 (w, v * 2, x); } return z; } int main(void) { long int a = 1; a = fn3(a, &fn4); return a - 5; } $ cat extern2.c // gcc -o extern extern.c extern2.c -g -O long int fn2 (long int a, long int b, long int c) { long int q = 2 * a; return q + 5; } long int fn4 (long int *i, long int j) { return *i << j; } $ gcc -o extern extern.c extern2.c -g -O $ stap -L 'process("extern").function("main").callee("*")' process("/home/yyz/jlebon/codebase/systemtap/systemtap/temp/extern").function("fn3@/home/yyz/jlebon/codebase/systemtap/systemtap/temp/extern.c:7") $x:long int $fn4:void* $w2:long int $ $ stap -L 'process("extern").function("fn3").callee("*")' process("/home/yyz/jlebon/codebase/systemtap/systemtap/temp/extern").function("fn2@/home/yyz/jlebon/codebase/systemtap/systemtap/temp/extern2.c:4") $a:long int $b:long int $c:long int $q:long int $ > Note however that call site DIEs are not guaranteed to be emitted for all > call sites (DW_TAG_subprogram attributes such as DW_AT_all_call_sites could > be examined to determine if they're all there, if it matters to us). Unfortunately, there is a slight issue here as well. DW_AT_all_call_sites only guarantees that all tail calls and normal calls have a corresponding DW_TAG_call_site DIE, but it makes no guarantee regarding inlined functions. In other words, we have no way of determining whether callee("*") truly caught every call possible. The DWARF issue (see [1] in comment 4) does have a new flag to that effect, DW_AT_all_source_call_sites, which, if present, indicates that all inlines, normal, and tail calls are present. Until this is implemented in gcc, we can make no guarantee on whether callee("*") is completely thorough. -- You are receiving this mail because: You are the assignee for the bug.