Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
B
bcc
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
bcc
Commits
7e78f3a6
Commit
7e78f3a6
authored
Jan 16, 2017
by
4ast
Committed by
GitHub
Jan 16, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #875 from pchaigno/target-process-library
Use targeted process to resolve library names
parents
9367ea5c
81654bf7
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
124 additions
and
35 deletions
+124
-35
src/cc/BPF.cc
src/cc/BPF.cc
+1
-1
src/cc/bcc_proc.c
src/cc/bcc_proc.c
+54
-4
src/cc/bcc_proc.h
src/cc/bcc_proc.h
+2
-1
src/cc/bcc_syms.cc
src/cc/bcc_syms.cc
+3
-3
src/cc/bcc_syms.h
src/cc/bcc_syms.h
+1
-1
src/cc/usdt.cc
src/cc/usdt.cc
+2
-1
src/lua/bcc/libbcc.lua
src/lua/bcc/libbcc.lua
+2
-1
src/lua/bcc/sym.lua
src/lua/bcc/sym.lua
+8
-3
src/python/bcc/__init__.py
src/python/bcc/__init__.py
+23
-14
src/python/bcc/libbcc.py
src/python/bcc/libbcc.py
+6
-4
tests/cc/test_c_api.cc
tests/cc/test_c_api.cc
+22
-2
No files found.
src/cc/BPF.cc
View file @
7e78f3a6
...
...
@@ -464,7 +464,7 @@ StatusTuple BPF::check_binary_symbol(const std::string& binary_path,
const
std
::
string
&
symbol
,
uint64_t
symbol_addr
,
bcc_symbol
*
output
)
{
int
res
=
bcc_resolve_symname
(
binary_path
.
c_str
(),
symbol
.
c_str
(),
symbol_addr
,
output
);
symbol_addr
,
0
,
output
);
if
(
res
<
0
)
return
StatusTuple
(
-
1
,
"Unable to find offset for binary %s symbol %s address %lx"
,
...
...
src/cc/bcc_proc.c
View file @
7e78f3a6
...
...
@@ -24,6 +24,7 @@
#include <stdint.h>
#include <ctype.h>
#include <stdio.h>
#include <math.h>
#include "bcc_perf_map.h"
#include "bcc_proc.h"
...
...
@@ -307,13 +308,57 @@ static bool match_so_flags(int flags) {
return
true
;
}
const
char
*
bcc_procutils_which_so
(
const
char
*
libname
)
{
static
bool
which_so_in_process
(
const
char
*
libname
,
int
pid
,
char
*
libpath
)
{
int
ret
,
found
=
false
;
char
endline
[
4096
],
*
mapname
=
NULL
,
*
newline
;
char
mappings_file
[
128
];
const
size_t
search_len
=
strlen
(
libname
)
+
strlen
(
"/lib."
);
char
search1
[
search_len
+
1
];
char
search2
[
search_len
+
1
];
sprintf
(
mappings_file
,
"/proc/%ld/maps"
,
(
long
)
pid
);
FILE
*
fp
=
fopen
(
mappings_file
,
"r"
);
if
(
!
fp
)
return
NULL
;
snprintf
(
search1
,
search_len
+
1
,
"/lib%s."
,
libname
);
snprintf
(
search2
,
search_len
+
1
,
"/lib%s-"
,
libname
);
do
{
ret
=
fscanf
(
fp
,
"%*x-%*x %*s %*x %*s %*d"
);
if
(
!
fgets
(
endline
,
sizeof
(
endline
),
fp
))
break
;
mapname
=
endline
;
newline
=
strchr
(
endline
,
'\n'
);
if
(
newline
)
newline
[
0
]
=
'\0'
;
while
(
isspace
(
mapname
[
0
]))
mapname
++
;
if
(
strstr
(
mapname
,
".so"
)
&&
(
strstr
(
mapname
,
search1
)
||
strstr
(
mapname
,
search2
)))
{
found
=
true
;
memcpy
(
libpath
,
mapname
,
strlen
(
mapname
)
+
1
);
break
;
}
}
while
(
ret
!=
EOF
);
fclose
(
fp
);
return
found
;
}
char
*
bcc_procutils_which_so
(
const
char
*
libname
,
int
pid
)
{
const
size_t
soname_len
=
strlen
(
libname
)
+
strlen
(
"lib.so"
);
char
soname
[
soname_len
+
1
];
char
libpath
[
4096
];
int
i
;
if
(
strchr
(
libname
,
'/'
))
return
libname
;
return
strdup
(
libname
);
if
(
pid
&&
which_so_in_process
(
libname
,
pid
,
libpath
))
return
strdup
(
libpath
);
if
(
lib_cache_count
<
0
)
return
NULL
;
...
...
@@ -327,8 +372,13 @@ const char *bcc_procutils_which_so(const char *libname) {
for
(
i
=
0
;
i
<
lib_cache_count
;
++
i
)
{
if
(
!
strncmp
(
lib_cache
[
i
].
libname
,
soname
,
soname_len
)
&&
match_so_flags
(
lib_cache
[
i
].
flags
))
return
lib_cache
[
i
].
path
;
match_so_flags
(
lib_cache
[
i
].
flags
))
{
return
strdup
(
lib_cache
[
i
].
path
);
}
}
return
NULL
;
}
void
bcc_procutils_free
(
const
char
*
ptr
)
{
free
((
void
*
)
ptr
);
}
src/cc/bcc_proc.h
View file @
7e78f3a6
...
...
@@ -27,11 +27,12 @@ extern "C" {
typedef
int
(
*
bcc_procutils_modulecb
)(
const
char
*
,
uint64_t
,
uint64_t
,
void
*
);
typedef
void
(
*
bcc_procutils_ksymcb
)(
const
char
*
,
uint64_t
,
void
*
);
c
onst
char
*
bcc_procutils_which_so
(
const
char
*
libname
);
c
har
*
bcc_procutils_which_so
(
const
char
*
libname
,
int
pid
);
char
*
bcc_procutils_which
(
const
char
*
binpath
);
int
bcc_procutils_each_module
(
int
pid
,
bcc_procutils_modulecb
callback
,
void
*
payload
);
int
bcc_procutils_each_ksym
(
bcc_procutils_ksymcb
callback
,
void
*
payload
);
void
bcc_procutils_free
(
const
char
*
ptr
);
#ifdef __cplusplus
}
...
...
src/cc/bcc_syms.cc
View file @
7e78f3a6
...
...
@@ -304,7 +304,7 @@ int bcc_foreach_symbol(const char *module, SYM_CB cb) {
}
int
bcc_resolve_symname
(
const
char
*
module
,
const
char
*
symname
,
const
uint64_t
addr
,
struct
bcc_symbol
*
sym
)
{
const
uint64_t
addr
,
int
pid
,
struct
bcc_symbol
*
sym
)
{
uint64_t
load_addr
;
sym
->
module
=
NULL
;
...
...
@@ -315,9 +315,9 @@ int bcc_resolve_symname(const char *module, const char *symname,
return
-
1
;
if
(
strchr
(
module
,
'/'
))
{
sym
->
module
=
module
;
sym
->
module
=
strdup
(
module
)
;
}
else
{
sym
->
module
=
bcc_procutils_which_so
(
module
);
sym
->
module
=
bcc_procutils_which_so
(
module
,
pid
);
}
if
(
sym
->
module
==
NULL
)
...
...
src/cc/bcc_syms.h
View file @
7e78f3a6
...
...
@@ -43,7 +43,7 @@ int bcc_resolve_global_addr(int pid, const char *module, const uint64_t address,
int
bcc_foreach_symbol
(
const
char
*
module
,
SYM_CB
cb
);
int
bcc_find_symbol_addr
(
struct
bcc_symbol
*
sym
);
int
bcc_resolve_symname
(
const
char
*
module
,
const
char
*
symname
,
const
uint64_t
addr
,
struct
bcc_symbol
*
sym
);
const
uint64_t
addr
,
int
pid
,
struct
bcc_symbol
*
sym
);
#ifdef __cplusplus
}
#endif
...
...
src/cc/usdt.cc
View file @
7e78f3a6
...
...
@@ -223,8 +223,9 @@ std::string Context::resolve_bin_path(const std::string &bin_path) {
if
(
char
*
which
=
bcc_procutils_which
(
bin_path
.
c_str
()))
{
result
=
which
;
::
free
(
which
);
}
else
if
(
c
onst
char
*
which_so
=
bcc_procutils_which_so
(
bin_path
.
c_str
()
))
{
}
else
if
(
c
har
*
which_so
=
bcc_procutils_which_so
(
bin_path
.
c_str
(),
0
))
{
result
=
which_so
;
::
free
(
which_so
);
}
return
result
;
...
...
src/lua/bcc/libbcc.lua
View file @
7e78f3a6
...
...
@@ -109,7 +109,8 @@ struct bcc_symbol {
};
int bcc_resolve_symname(const char *module, const char *symname, const uint64_t addr,
struct bcc_symbol *sym);
int pid, struct bcc_symbol *sym);
void bcc_procutils_free(const char *ptr);
void *bcc_symcache_new(int pid);
int bcc_symcache_resolve(void *symcache, uint64_t addr, struct bcc_symbol *sym);
void bcc_symcache_refresh(void *resolver);
...
...
src/lua/bcc/sym.lua
View file @
7e78f3a6
...
...
@@ -32,15 +32,20 @@ end
local
function
check_path_symbol
(
module
,
symname
,
addr
)
local
sym
=
SYM
()
if
libbcc
.
bcc_resolve_symname
(
module
,
symname
,
addr
or
0x0
,
sym
)
<
0
then
local
module_path
if
libbcc
.
bcc_resolve_symname
(
module
,
symname
,
addr
or
0x0
,
0
,
sym
)
<
0
then
if
sym
[
0
].
module
==
nil
then
error
(
"could not find library '%s' in the library path"
%
module
)
else
module_path
=
ffi
.
string
(
sym
[
0
].
module
)
libbcc
.
bcc_procutils_free
(
sym
[
0
].
module
)
error
(
"failed to resolve symbol '%s' in '%s'"
%
{
symname
,
ffi
.
string
(
sym
[
0
].
module
)
})
symname
,
module_path
})
end
end
return
ffi
.
string
(
sym
[
0
].
module
),
sym
[
0
].
offset
module_path
=
ffi
.
string
(
sym
[
0
].
module
)
libbcc
.
bcc_procutils_free
(
sym
[
0
].
module
)
return
module_path
,
sym
[
0
].
offset
end
return
{
create_cache
=
create_cache
,
check_path_symbol
=
check_path_symbol
}
src/python/bcc/__init__.py
View file @
7e78f3a6
...
...
@@ -554,20 +554,28 @@ class BPF(object):
@
classmethod
def
_check_path_symbol
(
cls
,
module
,
symname
,
addr
):
def
_check_path_symbol
(
cls
,
module
,
symname
,
addr
,
pid
):
sym
=
bcc_symbol
()
psym
=
ct
.
pointer
(
sym
)
c_pid
=
0
if
pid
==
-
1
else
pid
if
lib
.
bcc_resolve_symname
(
module
.
encode
(
"ascii"
),
symname
.
encode
(
"ascii"
),
addr
or
0x0
,
psym
)
<
0
:
symname
.
encode
(
"ascii"
),
addr
or
0x0
,
c_pid
,
psym
)
<
0
:
if
not
sym
.
module
:
raise
Exception
(
"could not find library %s"
%
module
)
lib
.
bcc_procutils_free
(
sym
.
module
)
raise
Exception
(
"could not determine address of symbol %s"
%
symname
)
return
sym
.
module
.
decode
(),
sym
.
offset
module_path
=
ct
.
cast
(
sym
.
module
,
ct
.
c_char_p
).
value
.
decode
()
lib
.
bcc_procutils_free
(
sym
.
module
)
return
module_path
,
sym
.
offset
@
staticmethod
def
find_library
(
libname
):
res
=
lib
.
bcc_procutils_which_so
(
libname
.
encode
(
"ascii"
))
return
res
if
res
is
None
else
res
.
decode
()
res
=
lib
.
bcc_procutils_which_so
(
libname
.
encode
(
"ascii"
),
0
)
if
not
res
:
return
None
libpath
=
ct
.
cast
(
res
,
ct
.
c_char_p
).
value
.
decode
()
lib
.
bcc_procutils_free
(
res
)
return
libpath
@
staticmethod
def
get_tracepoints
(
tp_re
):
...
...
@@ -736,7 +744,8 @@ class BPF(object):
Libraries can be given in the name argument without the lib prefix, or
with the full path (/usr/lib/...). Binaries can be given only with the
full path (/bin/sh).
full path (/bin/sh). If a PID is given, the uprobe will attach to the
version of the library used by the process.
Example: BPF(text).attach_uprobe("c", "malloc")
BPF(text).attach_uprobe("/usr/bin/python", "main")
...
...
@@ -753,7 +762,7 @@ class BPF(object):
group_fd
=
group_fd
)
return
(
path
,
addr
)
=
BPF
.
_check_path_symbol
(
name
,
sym
,
addr
)
(
path
,
addr
)
=
BPF
.
_check_path_symbol
(
name
,
sym
,
addr
,
pid
)
self
.
_check_probe_quota
(
1
)
fn
=
self
.
load_func
(
fn_name
,
BPF
.
KPROBE
)
...
...
@@ -768,15 +777,15 @@ class BPF(object):
self
.
_add_uprobe
(
ev_name
,
res
)
return
self
def
detach_uprobe
(
self
,
name
=
""
,
sym
=
""
,
addr
=
None
):
"""detach_uprobe(name="", sym="", addr=None)
def
detach_uprobe
(
self
,
name
=
""
,
sym
=
""
,
addr
=
None
,
pid
=-
1
):
"""detach_uprobe(name="", sym="", addr=None
, pid=-1
)
Stop running a bpf function that is attached to symbol 'sym' in library
or binary 'name'.
"""
name
=
str
(
name
)
(
path
,
addr
)
=
BPF
.
_check_path_symbol
(
name
,
sym
,
addr
)
(
path
,
addr
)
=
BPF
.
_check_path_symbol
(
name
,
sym
,
addr
,
pid
)
ev_name
=
"p_%s_0x%x"
%
(
self
.
_probe_repl
.
sub
(
"_"
,
path
),
addr
)
if
ev_name
not
in
self
.
open_uprobes
:
raise
Exception
(
"Uprobe %s is not attached"
%
ev_name
)
...
...
@@ -805,7 +814,7 @@ class BPF(object):
return
name
=
str
(
name
)
(
path
,
addr
)
=
BPF
.
_check_path_symbol
(
name
,
sym
,
addr
)
(
path
,
addr
)
=
BPF
.
_check_path_symbol
(
name
,
sym
,
addr
,
pid
)
self
.
_check_probe_quota
(
1
)
fn
=
self
.
load_func
(
fn_name
,
BPF
.
KPROBE
)
...
...
@@ -820,15 +829,15 @@ class BPF(object):
self
.
_add_uprobe
(
ev_name
,
res
)
return
self
def
detach_uretprobe
(
self
,
name
=
""
,
sym
=
""
,
addr
=
None
):
"""detach_uretprobe(name="", sym="", addr=None)
def
detach_uretprobe
(
self
,
name
=
""
,
sym
=
""
,
addr
=
None
,
pid
=-
1
):
"""detach_uretprobe(name="", sym="", addr=None
, pid=-1
)
Stop running a bpf function that is attached to symbol 'sym' in library
or binary 'name'.
"""
name
=
str
(
name
)
(
path
,
addr
)
=
BPF
.
_check_path_symbol
(
name
,
sym
,
addr
)
(
path
,
addr
)
=
BPF
.
_check_path_symbol
(
name
,
sym
,
addr
,
pid
)
ev_name
=
"r_%s_0x%x"
%
(
self
.
_probe_repl
.
sub
(
"_"
,
path
),
addr
)
if
ev_name
not
in
self
.
open_uprobes
:
raise
Exception
(
"Uretprobe %s is not attached"
%
ev_name
)
...
...
src/python/bcc/libbcc.py
View file @
7e78f3a6
...
...
@@ -126,16 +126,18 @@ class bcc_symbol(ct.Structure):
_fields_
=
[
(
'name'
,
ct
.
c_char_p
),
(
'demangle_name'
,
ct
.
c_char_p
),
(
'module'
,
ct
.
c_char_p
),
(
'module'
,
ct
.
POINTER
(
ct
.
c_char
)
),
(
'offset'
,
ct
.
c_ulonglong
),
]
lib
.
bcc_procutils_which_so
.
restype
=
ct
.
c_char_p
lib
.
bcc_procutils_which_so
.
argtypes
=
[
ct
.
c_char_p
]
lib
.
bcc_procutils_which_so
.
restype
=
ct
.
POINTER
(
ct
.
c_char
)
lib
.
bcc_procutils_which_so
.
argtypes
=
[
ct
.
c_char_p
,
ct
.
c_int
]
lib
.
bcc_procutils_free
.
restype
=
None
lib
.
bcc_procutils_free
.
argtypes
=
[
ct
.
c_void_p
]
lib
.
bcc_resolve_symname
.
restype
=
ct
.
c_int
lib
.
bcc_resolve_symname
.
argtypes
=
[
ct
.
c_char_p
,
ct
.
c_char_p
,
ct
.
c_ulonglong
,
ct
.
POINTER
(
bcc_symbol
)]
ct
.
c_char_p
,
ct
.
c_char_p
,
ct
.
c_ulonglong
,
ct
.
c_int
,
ct
.
POINTER
(
bcc_symbol
)]
_SYM_CB_TYPE
=
ct
.
CFUNCTYPE
(
ct
.
c_int
,
ct
.
c_char_p
,
ct
.
c_ulonglong
)
lib
.
bcc_foreach_symbol
.
restype
=
ct
.
c_int
...
...
tests/cc/test_c_api.cc
View file @
7e78f3a6
...
...
@@ -31,10 +31,19 @@
using
namespace
std
;
TEST_CASE
(
"shared object resolution"
,
"[c_api]"
)
{
c
onst
char
*
libm
=
bcc_procutils_which_so
(
"m"
);
c
har
*
libm
=
bcc_procutils_which_so
(
"m"
,
0
);
REQUIRE
(
libm
);
REQUIRE
(
libm
[
0
]
==
'/'
);
REQUIRE
(
string
(
libm
).
find
(
"libm.so"
)
!=
string
::
npos
);
free
(
libm
);
}
TEST_CASE
(
"shared object resolution using loaded libraries"
,
"[c_api]"
)
{
char
*
libelf
=
bcc_procutils_which_so
(
"elf"
,
getpid
());
REQUIRE
(
libelf
);
REQUIRE
(
libelf
[
0
]
==
'/'
);
REQUIRE
(
string
(
libelf
).
find
(
"libelf"
)
!=
string
::
npos
);
free
(
libelf
);
}
TEST_CASE
(
"binary resolution with `which`"
,
"[c_api]"
)
{
...
...
@@ -58,10 +67,21 @@ TEST_CASE("list all kernel symbols", "[c_api]") {
TEST_CASE
(
"resolve symbol name in external library"
,
"[c_api]"
)
{
struct
bcc_symbol
sym
;
REQUIRE
(
bcc_resolve_symname
(
"c"
,
"malloc"
,
0x0
,
&
sym
)
==
0
);
REQUIRE
(
bcc_resolve_symname
(
"c"
,
"malloc"
,
0x0
,
0
,
&
sym
)
==
0
);
REQUIRE
(
string
(
sym
.
module
).
find
(
"libc.so"
)
!=
string
::
npos
);
REQUIRE
(
sym
.
module
[
0
]
==
'/'
);
REQUIRE
(
sym
.
offset
!=
0
);
bcc_procutils_free
(
sym
.
module
);
}
TEST_CASE
(
"resolve symbol name in external library using loaded libraries"
,
"[c_api]"
)
{
struct
bcc_symbol
sym
;
REQUIRE
(
bcc_resolve_symname
(
"bcc"
,
"bcc_procutils_which"
,
0x0
,
getpid
(),
&
sym
)
==
0
);
REQUIRE
(
string
(
sym
.
module
).
find
(
"libbcc.so"
)
!=
string
::
npos
);
REQUIRE
(
sym
.
module
[
0
]
==
'/'
);
REQUIRE
(
sym
.
offset
!=
0
);
bcc_procutils_free
(
sym
.
module
);
}
extern
"C"
int
_a_test_function
(
const
char
*
a_string
)
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment