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
cb3d1618
Commit
cb3d1618
authored
May 19, 2017
by
Brenden Blanco
Committed by
GitHub
May 19, 2017
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #1164 from palmtenor/symboloptions
Add ability for users to control symboling behavior
parents
381f03db
cf130834
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
206 additions
and
113 deletions
+206
-113
src/cc/BPF.cc
src/cc/BPF.cc
+2
-1
src/cc/BPFTable.cc
src/cc/BPFTable.cc
+1
-1
src/cc/bcc_elf.c
src/cc/bcc_elf.c
+35
-14
src/cc/bcc_elf.h
src/cc/bcc_elf.h
+4
-2
src/cc/bcc_perf_map.c
src/cc/bcc_perf_map.c
+1
-1
src/cc/bcc_perf_map.h
src/cc/bcc_perf_map.h
+2
-2
src/cc/bcc_syms.cc
src/cc/bcc_syms.cc
+70
-54
src/cc/bcc_syms.h
src/cc/bcc_syms.h
+30
-4
src/cc/syms.h
src/cc/syms.h
+10
-7
src/cc/usdt_args.cc
src/cc/usdt_args.cc
+10
-3
src/lua/bcc/libbcc.lua
src/lua/bcc/libbcc.lua
+9
-2
src/lua/bcc/sym.lua
src/lua/bcc/sym.lua
+2
-2
src/python/bcc/__init__.py
src/python/bcc/__init__.py
+11
-8
src/python/bcc/libbcc.py
src/python/bcc/libbcc.py
+11
-4
tests/cc/test_c_api.cc
tests/cc/test_c_api.cc
+8
-8
No files found.
src/cc/BPF.cc
View file @
cb3d1618
...
...
@@ -469,8 +469,9 @@ StatusTuple BPF::unload_func(const std::string& func_name) {
StatusTuple
BPF
::
check_binary_symbol
(
const
std
::
string
&
binary_path
,
const
std
::
string
&
symbol
,
uint64_t
symbol_addr
,
bcc_symbol
*
output
)
{
// TODO: Fix output.module memory leak here
int
res
=
bcc_resolve_symname
(
binary_path
.
c_str
(),
symbol
.
c_str
(),
symbol_addr
,
0
,
output
);
symbol_addr
,
0
,
nullptr
,
output
);
if
(
res
<
0
)
return
StatusTuple
(
-
1
,
"Unable to find offset for binary %s symbol %s address %lx"
,
...
...
src/cc/BPFTable.cc
View file @
cb3d1618
...
...
@@ -110,7 +110,7 @@ std::vector<std::string> BPFStackTable::get_stack_symbol(int stack_id,
if
(
pid
<
0
)
pid
=
-
1
;
if
(
pid_sym_
.
find
(
pid
)
==
pid_sym_
.
end
())
pid_sym_
[
pid
]
=
bcc_symcache_new
(
pid
);
pid_sym_
[
pid
]
=
bcc_symcache_new
(
pid
,
nullptr
);
void
*
cache
=
pid_sym_
[
pid
];
bcc_symbol
symbol
;
...
...
src/cc/bcc_elf.c
View file @
cb3d1618
...
...
@@ -26,7 +26,10 @@
#include <gelf.h>
#include "bcc_elf.h"
#include "bcc_syms.h"
#define NT_STAPSDT 3
#define ELF_ST_TYPE(x) (((uint32_t) x) & 0xf)
static
int
openelf
(
const
char
*
path
,
Elf
**
elf_out
,
int
*
fd_out
)
{
if
(
elf_version
(
EV_CURRENT
)
==
EV_NONE
)
...
...
@@ -150,6 +153,7 @@ int bcc_elf_foreach_usdt(const char *path, bcc_elf_probecb callback,
}
static
int
list_in_scn
(
Elf
*
e
,
Elf_Scn
*
section
,
size_t
stridx
,
size_t
symsize
,
struct
bcc_symbol_option
*
option
,
bcc_elf_symcb
callback
,
void
*
payload
)
{
Elf_Data
*
data
=
NULL
;
...
...
@@ -168,8 +172,17 @@ static int list_in_scn(Elf *e, Elf_Scn *section, size_t stridx, size_t symsize,
if
((
name
=
elf_strptr
(
e
,
stridx
,
sym
.
st_name
))
==
NULL
)
continue
;
if
(
name
[
0
]
==
0
)
continue
;
if
(
sym
.
st_value
==
0
)
continue
;
uint32_t
flag
=
1
<<
ELF_ST_TYPE
(
sym
.
st_info
);
if
(
!
(
option
->
use_symbol_type
&
flag
))
continue
;
if
(
callback
(
name
,
sym
.
st_value
,
sym
.
st_size
,
sym
.
st_info
,
payload
)
<
0
)
if
(
callback
(
name
,
sym
.
st_value
,
sym
.
st_size
,
payload
)
<
0
)
return
1
;
// signal termination to caller
}
}
...
...
@@ -177,7 +190,8 @@ static int list_in_scn(Elf *e, Elf_Scn *section, size_t stridx, size_t symsize,
return
0
;
}
static
int
listsymbols
(
Elf
*
e
,
bcc_elf_symcb
callback
,
void
*
payload
)
{
static
int
listsymbols
(
Elf
*
e
,
bcc_elf_symcb
callback
,
void
*
payload
,
struct
bcc_symbol_option
*
option
)
{
Elf_Scn
*
section
=
NULL
;
while
((
section
=
elf_nextscn
(
e
,
section
))
!=
0
)
{
...
...
@@ -190,7 +204,7 @@ static int listsymbols(Elf *e, bcc_elf_symcb callback, void *payload) {
continue
;
int
rc
=
list_in_scn
(
e
,
section
,
header
.
sh_link
,
header
.
sh_entsize
,
callback
,
payload
);
option
,
callback
,
payload
);
if
(
rc
==
1
)
break
;
// callback signaled termination
...
...
@@ -347,7 +361,8 @@ static int verify_checksum(const char *file, unsigned int crc) {
return
actual
==
crc
;
}
static
char
*
find_debug_via_debuglink
(
Elf
*
e
,
const
char
*
binpath
)
{
static
char
*
find_debug_via_debuglink
(
Elf
*
e
,
const
char
*
binpath
,
int
check_crc
)
{
char
fullpath
[
PATH_MAX
];
char
*
bindir
=
NULL
;
char
*
res
=
NULL
;
...
...
@@ -386,9 +401,9 @@ static char *find_debug_via_debuglink(Elf *e, const char *binpath) {
DONE:
free
(
bindir
);
if
(
verify_checksum
(
res
,
crc
))
return
res
;
if
(
check_crc
&&
!
verify_checksum
(
res
,
crc
))
return
NULL
;
return
res
;
}
static
char
*
find_debug_via_buildid
(
Elf
*
e
)
{
...
...
@@ -412,11 +427,15 @@ static char *find_debug_via_buildid(Elf *e) {
}
static
int
foreach_sym_core
(
const
char
*
path
,
bcc_elf_symcb
callback
,
void
*
payload
,
int
is_debug_file
)
{
struct
bcc_symbol_option
*
option
,
void
*
payload
,
int
is_debug_file
)
{
Elf
*
e
;
int
fd
,
res
;
char
*
debug_file
;
if
(
!
option
)
return
-
1
;
if
(
openelf
(
path
,
&
e
,
&
fd
)
<
0
)
return
-
1
;
...
...
@@ -424,27 +443,29 @@ static int foreach_sym_core(const char *path, bcc_elf_symcb callback,
// using the build-id section, then using the debuglink section. These are
// also the rules that GDB folows.
// See: https://sourceware.org/gdb/onlinedocs/gdb/Separate-Debug-Files.html
if
(
!
is_debug_file
)
{
if
(
option
->
use_debug_file
&&
!
is_debug_file
)
{
// The is_debug_file argument helps avoid infinitely resolving debuginfo
// files for debuginfo files and so on.
debug_file
=
find_debug_via_buildid
(
e
);
if
(
!
debug_file
)
debug_file
=
find_debug_via_debuglink
(
e
,
path
);
debug_file
=
find_debug_via_debuglink
(
e
,
path
,
option
->
check_debug_file_crc
);
if
(
debug_file
)
{
foreach_sym_core
(
debug_file
,
callback
,
payload
,
1
);
foreach_sym_core
(
debug_file
,
callback
,
option
,
payload
,
1
);
free
(
debug_file
);
}
}
res
=
listsymbols
(
e
,
callback
,
payload
);
res
=
listsymbols
(
e
,
callback
,
payload
,
option
);
elf_end
(
e
);
close
(
fd
);
return
res
;
}
int
bcc_elf_foreach_sym
(
const
char
*
path
,
bcc_elf_symcb
callback
,
void
*
payload
)
{
return
foreach_sym_core
(
path
,
callback
,
payload
,
0
);
void
*
option
,
void
*
payload
)
{
return
foreach_sym_core
(
path
,
callback
,
(
struct
bcc_symbol_option
*
)
option
,
payload
,
0
);
}
static
int
loadaddr
(
Elf
*
e
,
uint64_t
*
addr
)
{
...
...
src/cc/bcc_elf.h
View file @
cb3d1618
...
...
@@ -34,13 +34,15 @@ struct bcc_elf_usdt {
typedef
void
(
*
bcc_elf_probecb
)(
const
char
*
,
const
struct
bcc_elf_usdt
*
,
void
*
);
typedef
int
(
*
bcc_elf_symcb
)(
const
char
*
,
uint64_t
,
uint64_t
,
int
,
void
*
);
// Symbol name, start address, length, payload
typedef
int
(
*
bcc_elf_symcb
)(
const
char
*
,
uint64_t
,
uint64_t
,
void
*
);
int
bcc_elf_foreach_usdt
(
const
char
*
path
,
bcc_elf_probecb
callback
,
void
*
payload
);
int
bcc_elf_loadaddr
(
const
char
*
path
,
uint64_t
*
address
);
int
bcc_elf_foreach_sym
(
const
char
*
path
,
bcc_elf_symcb
callback
,
void
*
payload
);
void
*
option
,
void
*
payload
);
int
bcc_elf_get_type
(
const
char
*
path
);
int
bcc_elf_is_shared_obj
(
const
char
*
path
);
...
...
src/cc/bcc_perf_map.c
View file @
cb3d1618
...
...
@@ -109,7 +109,7 @@ int bcc_perf_map_foreach_sym(const char *path, bcc_perf_map_symcb callback,
if
(
newline
)
newline
[
0
]
=
'\0'
;
callback
(
cursor
,
begin
,
len
,
0
,
payload
);
callback
(
cursor
,
begin
,
len
,
payload
);
}
free
(
line
);
...
...
src/cc/bcc_perf_map.h
View file @
cb3d1618
...
...
@@ -24,8 +24,8 @@ extern "C" {
#include <stdbool.h>
#include <unistd.h>
typedef
int
(
*
bcc_perf_map_symcb
)(
const
char
*
,
uint64_t
,
uint64_t
,
int
,
void
*
);
// Symbol name, start address, length, payload
typedef
int
(
*
bcc_perf_map_symcb
)(
const
char
*
,
uint64_t
,
uint64_t
,
void
*
);
bool
bcc_is_perf_map
(
const
char
*
path
);
...
...
src/cc/bcc_syms.cc
View file @
cb3d1618
...
...
@@ -15,6 +15,7 @@
*/
#include <cxxabi.h>
#include <cstring>
#include <fcntl.h>
#include <linux/elf.h>
#include <string.h>
...
...
@@ -31,6 +32,10 @@
#include "syms.h"
#include "vendor/tinyformat.hpp"
#ifndef STT_GNU_IFUNC
#define STT_GNU_IFUNC 10
#endif
ino_t
ProcStat
::
getinode_
()
{
struct
stat
s
;
return
(
!
stat
(
procfs_
.
c_str
(),
&
s
))
?
s
.
st_ino
:
-
1
;
...
...
@@ -155,8 +160,16 @@ ProcMountNSGuard::~ProcMountNSGuard() {
setns
(
mount_ns_
->
self_fd_
,
CLONE_NEWNS
);
}
ProcSyms
::
ProcSyms
(
int
pid
)
ProcSyms
::
ProcSyms
(
int
pid
,
struct
bcc_symbol_option
*
option
)
:
pid_
(
pid
),
procstat_
(
pid
),
mount_ns_instance_
(
new
ProcMountNS
(
pid_
))
{
if
(
option
)
std
::
memcpy
(
&
symbol_option_
,
option
,
sizeof
(
bcc_symbol_option
));
else
symbol_option_
=
{
.
use_debug_file
=
1
,
.
check_debug_file_crc
=
1
,
.
use_symbol_type
=
(
1
<<
STT_FUNC
)
|
(
1
<<
STT_GNU_IFUNC
)
};
load_modules
();
}
...
...
@@ -179,7 +192,8 @@ int ProcSyms::_add_module(const char *modname, uint64_t start, uint64_t end,
[
=
](
const
ProcSyms
::
Module
&
m
)
{
return
m
.
name_
==
modname
;
});
if
(
it
==
ps
->
modules_
.
end
())
{
auto
module
=
Module
(
modname
,
check_mount_ns
?
ps
->
mount_ns_instance_
.
get
()
:
nullptr
);
modname
,
check_mount_ns
?
ps
->
mount_ns_instance_
.
get
()
:
nullptr
,
&
ps
->
symbol_option_
);
if
(
module
.
init
())
it
=
ps
->
modules_
.
insert
(
ps
->
modules_
.
end
(),
std
::
move
(
module
));
else
...
...
@@ -244,10 +258,12 @@ bool ProcSyms::resolve_name(const char *module, const char *name,
return
false
;
}
ProcSyms
::
Module
::
Module
(
const
char
*
name
,
ProcMountNS
*
mount_ns
)
ProcSyms
::
Module
::
Module
(
const
char
*
name
,
ProcMountNS
*
mount_ns
,
struct
bcc_symbol_option
*
option
)
:
name_
(
name
),
loaded_
(
false
),
mount_ns_
(
mount_ns
),
symbol_option_
(
option
),
type_
(
ModuleType
::
UNKNOWN
)
{}
bool
ProcSyms
::
Module
::
init
()
{
...
...
@@ -274,10 +290,10 @@ bool ProcSyms::Module::init() {
}
int
ProcSyms
::
Module
::
_add_symbol
(
const
char
*
symname
,
uint64_t
start
,
uint64_t
end
,
int
flags
,
void
*
p
)
{
uint64_t
size
,
void
*
p
)
{
Module
*
m
=
static_cast
<
Module
*>
(
p
);
auto
res
=
m
->
symnames_
.
emplace
(
symname
);
m
->
syms_
.
emplace_back
(
&*
(
res
.
first
),
start
,
end
,
flags
);
m
->
syms_
.
emplace_back
(
&*
(
res
.
first
),
start
,
size
);
return
0
;
}
...
...
@@ -291,7 +307,7 @@ void ProcSyms::Module::load_sym_table() {
if
(
type_
==
ModuleType
::
PERF_MAP
)
bcc_perf_map_foreach_sym
(
name_
.
c_str
(),
_add_symbol
,
this
);
if
(
type_
==
ModuleType
::
EXEC
||
type_
==
ModuleType
::
SO
)
bcc_elf_foreach_sym
(
name_
.
c_str
(),
_add_symbol
,
this
);
bcc_elf_foreach_sym
(
name_
.
c_str
(),
_add_symbol
,
symbol_option_
,
this
);
std
::
sort
(
syms_
.
begin
(),
syms_
.
end
());
}
...
...
@@ -367,10 +383,10 @@ bool ProcSyms::Module::find_addr(uint64_t offset, struct bcc_symbol *sym) {
extern
"C"
{
void
*
bcc_symcache_new
(
int
pid
)
{
void
*
bcc_symcache_new
(
int
pid
,
struct
bcc_symbol_option
*
option
)
{
if
(
pid
<
0
)
return
static_cast
<
void
*>
(
new
KSyms
());
return
static_cast
<
void
*>
(
new
ProcSyms
(
pid
));
return
static_cast
<
void
*>
(
new
ProcSyms
(
pid
,
option
));
}
void
bcc_free_symcache
(
void
*
symcache
,
int
pid
)
{
...
...
@@ -434,58 +450,52 @@ int bcc_resolve_global_addr(int pid, const char *module, const uint64_t address,
return
0
;
}
static
int
_find_sym
(
const
char
*
symname
,
uint64_t
addr
,
uint64_t
end
,
int
flags
,
void
*
payload
)
{
struct
bcc_symbol
*
sym
=
(
struct
bcc_symbol
*
)
payload
;
// TODO: check for actual function symbol in flags
if
(
!
strcmp
(
sym
->
name
,
symname
))
{
sym
->
offset
=
addr
;
return
-
1
;
}
return
0
;
}
int
bcc_find_symbol_addr
(
struct
bcc_symbol
*
sym
)
{
return
bcc_elf_foreach_sym
(
sym
->
module
,
_find_sym
,
sym
);
static
int
_sym_cb_wrapper
(
const
char
*
symname
,
uint64_t
addr
,
uint64_t
,
void
*
payload
)
{
SYM_CB
cb
=
(
SYM_CB
)
payload
;
return
cb
(
symname
,
addr
);
}
struct
sym_search_t
{
struct
bcc_symbol
*
syms
;
int
start
;
int
requested
;
int
*
actual
;
};
// see <elf.h>
#define ELF_TYPE_IS_FUNCTION(flags) (((flags) & 0xf) == 2)
int
bcc_foreach_function_symbol
(
const
char
*
module
,
SYM_CB
cb
)
{
if
(
module
==
0
||
cb
==
0
)
return
-
1
;
static
int
_list_sym
(
const
char
*
symname
,
uint64_t
addr
,
uint64_t
end
,
int
flags
,
void
*
payload
)
{
if
(
!
ELF_TYPE_IS_FUNCTION
(
flags
)
||
addr
==
0
)
return
0
;
static
struct
bcc_symbol_option
default_option
=
{
.
use_debug_file
=
1
,
.
check_debug_file_crc
=
1
,
.
use_symbol_type
=
(
1
<<
STT_FUNC
)
|
(
1
<<
STT_GNU_IFUNC
)
};
SYM_CB
cb
=
(
SYM_CB
)
payload
;
return
cb
(
symname
,
addr
);
return
bcc_elf_foreach_sym
(
module
,
_sym_cb_wrapper
,
&
default_option
,
(
void
*
)
cb
);
}
int
bcc_foreach_symbol
(
const
char
*
module
,
SYM_CB
cb
)
{
if
(
module
==
0
||
cb
==
0
)
static
int
_find_sym
(
const
char
*
symname
,
uint64_t
addr
,
uint64_t
,
void
*
payload
)
{
struct
bcc_symbol
*
sym
=
(
struct
bcc_symbol
*
)
payload
;
if
(
!
strcmp
(
sym
->
name
,
symname
))
{
sym
->
offset
=
addr
;
return
-
1
;
return
bcc_elf_foreach_sym
(
module
,
_list_sym
,
(
void
*
)
cb
)
;
}
return
0
;
}
int
bcc_resolve_symname
(
const
char
*
module
,
const
char
*
symname
,
const
uint64_t
addr
,
int
pid
,
struct
bcc_symbol
*
sym
)
{
const
uint64_t
addr
,
int
pid
,
struct
bcc_symbol_option
*
option
,
struct
bcc_symbol
*
sym
)
{
uint64_t
load_addr
;
sym
->
module
=
NULL
;
sym
->
name
=
NULL
;
sym
->
offset
=
0x0
;
static
struct
bcc_symbol_option
default_option
=
{
.
use_debug_file
=
1
,
.
check_debug_file_crc
=
1
,
.
use_symbol_type
=
BCC_SYM_ALL_TYPES
,
};
if
(
module
==
NULL
)
return
-
1
;
memset
(
sym
,
0
,
sizeof
(
bcc_symbol
));
if
(
strchr
(
module
,
'/'
))
{
sym
->
module
=
strdup
(
module
);
}
else
{
...
...
@@ -497,25 +507,31 @@ int bcc_resolve_symname(const char *module, const char *symname,
ProcMountNSGuard
g
(
pid
);
if
(
bcc_elf_loadaddr
(
sym
->
module
,
&
load_addr
)
<
0
)
{
sym
->
module
=
NULL
;
return
-
1
;
}
if
(
bcc_elf_loadaddr
(
sym
->
module
,
&
load_addr
)
<
0
)
goto
invalid_module
;
sym
->
name
=
symname
;
sym
->
offset
=
addr
;
if
(
option
==
NULL
)
option
=
&
default_option
;
if
(
sym
->
name
&&
sym
->
offset
==
0x0
)
if
(
bcc_find_symbol_addr
(
sym
)
<
0
)
{
sym
->
module
=
NULL
;
return
-
1
;
}
if
(
bcc_elf_foreach_sym
(
sym
->
module
,
_find_sym
,
option
,
sym
)
<
0
)
goto
invalid_module
;
if
(
sym
->
offset
==
0x0
)
return
-
1
;
goto
invalid_module
;
sym
->
offset
=
(
sym
->
offset
-
load_addr
);
return
0
;
invalid_module:
if
(
sym
->
module
)
{
::
free
(
const_cast
<
char
*>
(
sym
->
module
));
sym
->
module
=
NULL
;
}
return
-
1
;
}
void
*
bcc_enter_mount_ns
(
int
pid
)
{
...
...
src/cc/bcc_syms.h
View file @
cb3d1618
...
...
@@ -31,7 +31,15 @@ struct bcc_symbol {
typedef
int
(
*
SYM_CB
)(
const
char
*
symname
,
uint64_t
addr
);
void
*
bcc_symcache_new
(
int
pid
);
static
const
uint32_t
BCC_SYM_ALL_TYPES
=
65535
;
struct
bcc_symbol_option
{
int
use_debug_file
;
int
check_debug_file_crc
;
// Bitmask flags indicating what types of ELF symbols to use
uint32_t
use_symbol_type
;
};
void
*
bcc_symcache_new
(
int
pid
,
struct
bcc_symbol_option
*
option
);
void
bcc_free_symcache
(
void
*
symcache
,
int
pid
);
// The demangle_name pointer in bcc_symbol struct is returned from the
...
...
@@ -48,10 +56,28 @@ void bcc_symcache_refresh(void *resolver);
int
bcc_resolve_global_addr
(
int
pid
,
const
char
*
module
,
const
uint64_t
address
,
uint64_t
*
global
);
int
bcc_foreach_symbol
(
const
char
*
module
,
SYM_CB
cb
);
int
bcc_find_symbol_addr
(
struct
bcc_symbol
*
sym
);
// Call cb on every function symbol in the specified module. Uses simpler
// SYM_CB callback mainly for easier to use in Python API.
// Will prefer use debug file and check debug file CRC when reading the module.
int
bcc_foreach_function_symbol
(
const
char
*
module
,
SYM_CB
cb
);
// Find the offset of a symbol in a module binary. If addr is not zero, will
// calculate the offset using the provided addr and the module's load address.
//
// If pid is provided, will use it to help lookup the module in the Process and
// enter the Process's mount Namespace.
//
// If option is not NULL, will respect the specified options for lookup.
// Otherwise default option will apply, which is to use debug file, verify
// checksum, and try all types of symbols.
//
// Return 0 on success and -1 on failure. Output will be write to sym. After
// use, sym->module need to be freed if it's not empty.
int
bcc_resolve_symname
(
const
char
*
module
,
const
char
*
symname
,
const
uint64_t
addr
,
int
pid
,
struct
bcc_symbol
*
sym
);
const
uint64_t
addr
,
int
pid
,
struct
bcc_symbol_option
*
option
,
struct
bcc_symbol
*
sym
);
void
*
bcc_enter_mount_ns
(
int
pid
);
void
bcc_exit_mount_ns
(
void
**
guard
);
...
...
src/cc/syms.h
View file @
cb3d1618
...
...
@@ -24,6 +24,7 @@
#include <vector>
#include "file_desc.h"
#include "bcc_syms.h"
class
ProcStat
{
std
::
string
procfs_
;
...
...
@@ -97,12 +98,11 @@ private:
class
ProcSyms
:
SymbolCache
{
struct
Symbol
{
Symbol
(
const
std
::
string
*
name
,
uint64_t
start
,
uint64_t
size
,
int
flags
=
0
)
:
name
(
name
),
start
(
start
),
size
(
size
)
,
flags
(
flags
)
{}
Symbol
(
const
std
::
string
*
name
,
uint64_t
start
,
uint64_t
size
)
:
name
(
name
),
start
(
start
),
size
(
size
)
{}
const
std
::
string
*
name
;
uint64_t
start
;
uint64_t
size
;
int
flags
;
bool
operator
<
(
const
struct
Symbol
&
rhs
)
const
{
return
start
<
rhs
.
start
;
...
...
@@ -123,13 +123,15 @@ class ProcSyms : SymbolCache {
Range
(
uint64_t
s
,
uint64_t
e
)
:
start
(
s
),
end
(
e
)
{}
};
Module
(
const
char
*
name
,
ProcMountNS
*
mount_ns
);
Module
(
const
char
*
name
,
ProcMountNS
*
mount_ns
,
struct
bcc_symbol_option
*
option
);
bool
init
();
std
::
string
name_
;
std
::
vector
<
Range
>
ranges_
;
bool
loaded_
;
ProcMountNS
*
mount_ns_
;
bcc_symbol_option
*
symbol_option_
;
ModuleType
type_
;
std
::
unordered_set
<
std
::
string
>
symnames_
;
...
...
@@ -141,20 +143,21 @@ class ProcSyms : SymbolCache {
bool
find_addr
(
uint64_t
offset
,
struct
bcc_symbol
*
sym
);
bool
find_name
(
const
char
*
symname
,
uint64_t
*
addr
);
static
int
_add_symbol
(
const
char
*
symname
,
uint64_t
start
,
uint64_t
end
,
int
flags
,
void
*
p
);
static
int
_add_symbol
(
const
char
*
symname
,
uint64_t
start
,
uint64_t
size
,
void
*
p
);
};
int
pid_
;
std
::
vector
<
Module
>
modules_
;
ProcStat
procstat_
;
std
::
unique_ptr
<
ProcMountNS
>
mount_ns_instance_
;
bcc_symbol_option
symbol_option_
;
static
int
_add_module
(
const
char
*
,
uint64_t
,
uint64_t
,
bool
,
void
*
);
bool
load_modules
();
public:
ProcSyms
(
int
pid
);
ProcSyms
(
int
pid
,
struct
bcc_symbol_option
*
option
=
nullptr
);
virtual
void
refresh
();
virtual
bool
resolve_addr
(
uint64_t
addr
,
struct
bcc_symbol
*
sym
,
bool
demangle
=
true
);
virtual
bool
resolve_name
(
const
char
*
module
,
const
char
*
name
,
...
...
src/cc/usdt_args.cc
View file @
cb3d1618
...
...
@@ -35,14 +35,21 @@ std::string Argument::ctype() const {
bool
Argument
::
get_global_address
(
uint64_t
*
address
,
const
std
::
string
&
binpath
,
const
optional
<
int
>
&
pid
)
const
{
if
(
pid
)
{
return
ProcSyms
(
*
pid
)
static
struct
bcc_symbol_option
default_option
=
{
.
use_debug_file
=
1
,
.
check_debug_file_crc
=
1
,
.
use_symbol_type
=
BCC_SYM_ALL_TYPES
};
return
ProcSyms
(
*
pid
,
&
default_option
)
.
resolve_name
(
binpath
.
c_str
(),
deref_ident_
->
c_str
(),
address
);
}
if
(
!
bcc_elf_is_shared_obj
(
binpath
.
c_str
()))
{
struct
bcc_symbol
sym
=
{
deref_ident_
->
c_str
(),
binpath
.
c_str
(),
0x0
}
;
if
(
!
bcc_find_symbol_addr
(
&
sym
)
&&
sym
.
offset
)
{
struct
bcc_symbol
sym
;
if
(
bcc_resolve_symname
(
binpath
.
c_str
(),
deref_ident_
->
c_str
(),
0x0
,
-
1
,
nullptr
,
&
sym
)
==
0
)
{
*
address
=
sym
.
offset
;
if
(
sym
.
module
)
::
free
(
const_cast
<
char
*>
(
sym
.
module
));
return
true
;
}
}
...
...
src/lua/bcc/libbcc.lua
View file @
cb3d1618
...
...
@@ -114,10 +114,17 @@ struct bcc_symbol {
uint64_t offset;
};
struct bcc_symbol_option {
int use_debug_file;
int check_debug_file_crc;
uint32_t use_symbol_type;
};
int bcc_resolve_symname(const char *module, const char *symname, const uint64_t addr,
int pid, struct bcc_symbol *sym);
int pid, struct bcc_symbol_option *option,
struct bcc_symbol *sym);
void bcc_procutils_free(const char *ptr);
void *bcc_symcache_new(int pid);
void *bcc_symcache_new(int pid
, struct bcc_symbol_option *option
);
void bcc_symbol_free_demangle_name(struct bcc_symbol *sym);
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 @
cb3d1618
...
...
@@ -19,7 +19,7 @@ local SYM = ffi.typeof("struct bcc_symbol[1]")
local
function
create_cache
(
pid
)
return
{
_CACHE
=
libbcc
.
bcc_symcache_new
(
pid
or
-
1
),
_CACHE
=
libbcc
.
bcc_symcache_new
(
pid
or
-
1
,
nil
),
resolve
=
function
(
self
,
addr
)
local
sym
=
SYM
()
if
libbcc
.
bcc_symcache_resolve
(
self
.
_CACHE
,
addr
,
sym
)
<
0
then
...
...
@@ -35,7 +35,7 @@ end
local
function
check_path_symbol
(
module
,
symname
,
addr
,
pid
)
local
sym
=
SYM
()
local
module_path
if
libbcc
.
bcc_resolve_symname
(
module
,
symname
,
addr
or
0x0
,
pid
or
0
,
sym
)
<
0
then
if
libbcc
.
bcc_resolve_symname
(
module
,
symname
,
addr
or
0x0
,
pid
or
0
,
nil
,
sym
)
<
0
then
if
sym
[
0
].
module
==
nil
then
error
(
"could not find library '%s' in the library path"
%
module
)
else
...
...
src/python/bcc/__init__.py
View file @
cb3d1618
...
...
@@ -24,7 +24,7 @@ import errno
import
sys
basestring
=
(
unicode
if
sys
.
version_info
[
0
]
<
3
else
str
)
from
.libbcc
import
lib
,
_CB_TYPE
,
bcc_symbol
,
_SYM_CB_TYPE
from
.libbcc
import
lib
,
_CB_TYPE
,
bcc_symbol
,
bcc_symbol_option
,
_SYM_CB_TYPE
from
.table
import
Table
from
.perf
import
Perf
from
.utils
import
get_online_cpus
...
...
@@ -46,7 +46,8 @@ LOG_BUFFER_SIZE = 65536
class
SymbolCache
(
object
):
def
__init__
(
self
,
pid
):
self
.
cache
=
lib
.
bcc_symcache_new
(
pid
)
self
.
cache
=
lib
.
bcc_symcache_new
(
pid
,
ct
.
cast
(
None
,
ct
.
POINTER
(
bcc_symbol_option
)))
def
resolve
(
self
,
addr
,
demangle
):
"""
...
...
@@ -607,11 +608,12 @@ class BPF(object):
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
,
c_pid
,
psym
)
<
0
:
if
not
sym
.
module
:
raise
Exception
(
"could not find library %s"
%
module
)
lib
.
bcc_procutils_free
(
sym
.
module
)
if
lib
.
bcc_resolve_symname
(
module
.
encode
(
"ascii"
),
symname
.
encode
(
"ascii"
),
addr
or
0x0
,
c_pid
,
ct
.
cast
(
None
,
ct
.
POINTER
(
bcc_symbol_option
)),
psym
,
)
<
0
:
raise
Exception
(
"could not determine address of symbol %s"
%
symname
)
module_path
=
ct
.
cast
(
sym
.
module
,
ct
.
c_char_p
).
value
.
decode
()
lib
.
bcc_procutils_free
(
sym
.
module
)
...
...
@@ -773,7 +775,8 @@ class BPF(object):
addresses
.
append
((
dname
,
addr
))
return
0
res
=
lib
.
bcc_foreach_symbol
(
name
.
encode
(
'ascii'
),
_SYM_CB_TYPE
(
sym_cb
))
res
=
lib
.
bcc_foreach_function_symbol
(
name
.
encode
(
'ascii'
),
_SYM_CB_TYPE
(
sym_cb
))
if
res
<
0
:
raise
Exception
(
"Error %d enumerating symbols in %s"
%
(
res
,
name
))
return
addresses
...
...
src/python/bcc/libbcc.py
View file @
cb3d1618
...
...
@@ -133,6 +133,13 @@ class bcc_symbol(ct.Structure):
(
'offset'
,
ct
.
c_ulonglong
),
]
class
bcc_symbol_option
(
ct
.
Structure
):
_fields_
=
[
(
'use_debug_file'
,
ct
.
c_int
),
(
'check_debug_file_crc'
,
ct
.
c_int
),
(
'use_symbol_type'
,
ct
.
c_uint
),
]
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
...
...
@@ -142,14 +149,14 @@ lib.bcc_procutils_language.argtypes = [ct.c_int]
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
.
c_int
,
ct
.
POINTER
(
bcc_symbol
)]
ct
.
c_char_p
,
ct
.
c_char_p
,
ct
.
c_ulonglong
,
ct
.
c_int
,
ct
.
POINTER
(
bcc_symbol
_option
),
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
lib
.
bcc_foreach_symbol
.
argtypes
=
[
ct
.
c_char_p
,
_SYM_CB_TYPE
]
lib
.
bcc_foreach_
function_
symbol
.
restype
=
ct
.
c_int
lib
.
bcc_foreach_
function_
symbol
.
argtypes
=
[
ct
.
c_char_p
,
_SYM_CB_TYPE
]
lib
.
bcc_symcache_new
.
restype
=
ct
.
c_void_p
lib
.
bcc_symcache_new
.
argtypes
=
[
ct
.
c_int
]
lib
.
bcc_symcache_new
.
argtypes
=
[
ct
.
c_int
,
ct
.
POINTER
(
bcc_symbol_option
)
]
lib
.
bcc_free_symcache
.
restype
=
ct
.
c_void_p
lib
.
bcc_free_symcache
.
argtypes
=
[
ct
.
c_void_p
,
ct
.
c_int
]
...
...
tests/cc/test_c_api.cc
View file @
cb3d1618
...
...
@@ -92,7 +92,7 @@ TEST_CASE("file-backed mapping identification") {
TEST_CASE
(
"resolve symbol name in external library"
,
"[c_api]"
)
{
struct
bcc_symbol
sym
;
REQUIRE
(
bcc_resolve_symname
(
"c"
,
"malloc"
,
0x0
,
0
,
&
sym
)
==
0
);
REQUIRE
(
bcc_resolve_symname
(
"c"
,
"malloc"
,
0x0
,
0
,
nullptr
,
&
sym
)
==
0
);
REQUIRE
(
string
(
sym
.
module
).
find
(
"libc.so"
)
!=
string
::
npos
);
REQUIRE
(
sym
.
module
[
0
]
==
'/'
);
REQUIRE
(
sym
.
offset
!=
0
);
...
...
@@ -102,7 +102,7 @@ TEST_CASE("resolve symbol name in external library", "[c_api]") {
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
(
bcc_resolve_symname
(
"bcc"
,
"bcc_procutils_which"
,
0x0
,
getpid
(),
nullptr
,
&
sym
)
==
0
);
REQUIRE
(
string
(
sym
.
module
).
find
(
"libbcc.so"
)
!=
string
::
npos
);
REQUIRE
(
sym
.
module
[
0
]
==
'/'
);
REQUIRE
(
sym
.
offset
!=
0
);
...
...
@@ -195,7 +195,7 @@ static int mntns_func(void *arg) {
TEST_CASE
(
"resolve symbol addresses for a given PID"
,
"[c_api]"
)
{
struct
bcc_symbol
sym
;
void
*
resolver
=
bcc_symcache_new
(
getpid
());
void
*
resolver
=
bcc_symcache_new
(
getpid
()
,
nullptr
);
REQUIRE
(
resolver
);
...
...
@@ -240,7 +240,7 @@ TEST_CASE("resolve symbol addresses for a given PID", "[c_api]") {
child
=
spawn_child
(
0
,
true
,
true
,
mntns_func
);
REQUIRE
(
child
>
0
);
void
*
resolver
=
bcc_symcache_new
(
child
);
void
*
resolver
=
bcc_symcache_new
(
child
,
nullptr
);
REQUIRE
(
resolver
);
REQUIRE
(
bcc_symcache_resolve_name
(
resolver
,
"/tmp/libz.so.1"
,
"zlibVersion"
,
...
...
@@ -335,7 +335,7 @@ TEST_CASE("resolve symbols using /tmp/perf-pid.map", "[c_api]") {
child
=
spawn_child
(
map_addr
,
/* own_pidns */
false
,
false
,
perf_map_func
);
REQUIRE
(
child
>
0
);
void
*
resolver
=
bcc_symcache_new
(
child
);
void
*
resolver
=
bcc_symcache_new
(
child
,
nullptr
);
REQUIRE
(
resolver
);
REQUIRE
(
bcc_symcache_resolve
(
resolver
,
(
unsigned
long
long
)
map_addr
,
...
...
@@ -355,7 +355,7 @@ TEST_CASE("resolve symbols using /tmp/perf-pid.map", "[c_api]") {
child
=
spawn_child
(
map_addr
,
/* own_pidns */
true
,
false
,
perf_map_func
);
REQUIRE
(
child
>
0
);
void
*
resolver
=
bcc_symcache_new
(
child
);
void
*
resolver
=
bcc_symcache_new
(
child
,
nullptr
);
REQUIRE
(
resolver
);
REQUIRE
(
bcc_symcache_resolve
(
resolver
,
(
unsigned
long
long
)
map_addr
,
...
...
@@ -372,7 +372,7 @@ TEST_CASE("resolve symbols using /tmp/perf-pid.map", "[c_api]") {
perf_map_func_mntns
);
REQUIRE
(
child
>
0
);
void
*
resolver
=
bcc_symcache_new
(
child
);
void
*
resolver
=
bcc_symcache_new
(
child
,
nullptr
);
REQUIRE
(
resolver
);
REQUIRE
(
bcc_symcache_resolve
(
resolver
,
(
unsigned
long
long
)
map_addr
,
...
...
@@ -391,7 +391,7 @@ TEST_CASE("resolve symbols using /tmp/perf-pid.map", "[c_api]") {
string
path
=
perf_map_path
(
child
);
REQUIRE
(
make_perf_map_file
(
path
,
(
unsigned
long
long
)
map_addr
)
==
0
);
void
*
resolver
=
bcc_symcache_new
(
child
);
void
*
resolver
=
bcc_symcache_new
(
child
,
nullptr
);
REQUIRE
(
resolver
);
REQUIRE
(
bcc_symcache_resolve
(
resolver
,
(
unsigned
long
long
)
map_addr
,
...
...
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