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
48501550
Commit
48501550
authored
Apr 28, 2016
by
Vicent Marti
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cc: Split bcc_syms.cc into a C++ header file
parent
2ff8e576
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
171 additions
and
107 deletions
+171
-107
src/cc/bcc_syms.cc
src/cc/bcc_syms.cc
+65
-107
src/cc/bcc_syms.h
src/cc/bcc_syms.h
+3
-0
src/cc/syms.h
src/cc/syms.h
+103
-0
No files found.
src/cc/bcc_syms.cc
View file @
48501550
...
...
@@ -13,56 +13,41 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <vector>
#include <string>
#include <algorithm>
#include <unordered_map>
#include <s
ys/types
.h>
#include <s
tring
.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
#include "bcc_syms.h"
#include "bcc_proc.h"
#include "bcc_elf.h"
#include "bcc_proc.h"
#include "bcc_syms.h"
class
SymbolCache
{
public:
virtual
void
refresh
()
=
0
;
virtual
bool
resolve_addr
(
uint64_t
addr
,
struct
bcc_symbol
*
sym
)
=
0
;
virtual
bool
resolve_name
(
const
char
*
name
,
uint64_t
*
addr
)
=
0
;
};
class
KSyms
:
SymbolCache
{
struct
Symbol
{
Symbol
(
const
char
*
name
,
uint64_t
addr
)
:
name
(
name
),
addr
(
addr
)
{}
std
::
string
name
;
uint64_t
addr
;
bool
operator
<
(
const
Symbol
&
rhs
)
const
{
return
addr
<
rhs
.
addr
;
}
};
std
::
vector
<
Symbol
>
syms_
;
std
::
unordered_map
<
std
::
string
,
uint64_t
>
symnames_
;
static
void
_add_symbol
(
const
char
*
,
uint64_t
,
void
*
);
public:
virtual
bool
resolve_addr
(
uint64_t
addr
,
struct
bcc_symbol
*
sym
);
virtual
bool
resolve_name
(
const
char
*
name
,
uint64_t
*
addr
);
virtual
void
refresh
()
{
if
(
syms_
.
empty
())
{
bcc_procutils_each_ksym
(
_add_symbol
,
this
);
std
::
sort
(
syms_
.
begin
(),
syms_
.
end
());
}
}
};
#include "syms.h"
ino_t
ProcStat
::
getinode_
()
{
struct
stat
s
;
return
(
!
stat
(
procfs_
.
c_str
(),
&
s
))
?
s
.
st_ino
:
-
1
;
}
ProcStat
::
ProcStat
(
int
pid
)
:
inode_
(
-
1
)
{
char
buffer
[
128
];
snprintf
(
buffer
,
sizeof
(
buffer
),
"/proc/%d/exe"
,
pid
);
procfs_
=
buffer
;
}
void
KSyms
::
_add_symbol
(
const
char
*
symname
,
uint64_t
addr
,
void
*
p
)
{
KSyms
*
ks
=
static_cast
<
KSyms
*>
(
p
);
ks
->
syms_
.
emplace_back
(
symname
,
addr
);
}
void
KSyms
::
refresh
()
{
if
(
syms_
.
empty
())
{
bcc_procutils_each_ksym
(
_add_symbol
,
this
);
std
::
sort
(
syms_
.
begin
(),
syms_
.
end
());
}
}
bool
KSyms
::
resolve_addr
(
uint64_t
addr
,
struct
bcc_symbol
*
sym
)
{
refresh
();
...
...
@@ -80,7 +65,8 @@ bool KSyms::resolve_addr(uint64_t addr, struct bcc_symbol *sym) {
return
true
;
}
bool
KSyms
::
resolve_name
(
const
char
*
name
,
uint64_t
*
addr
)
{
bool
KSyms
::
resolve_name
(
const
char
*
_unused
,
const
char
*
name
,
uint64_t
*
addr
)
{
refresh
();
if
(
syms_
.
size
()
!=
symnames_
.
size
())
{
...
...
@@ -98,65 +84,6 @@ bool KSyms::resolve_name(const char *name, uint64_t *addr) {
return
true
;
}
class
ProcStat
{
std
::
string
procfs_
;
ino_t
inode_
;
ino_t
getinode_
()
{
struct
stat
s
;
return
(
!
stat
(
procfs_
.
c_str
(),
&
s
))
?
s
.
st_ino
:
-
1
;
}
public:
ProcStat
(
int
pid
)
:
inode_
(
-
1
)
{
char
buffer
[
128
];
snprintf
(
buffer
,
sizeof
(
buffer
),
"/proc/%d/exe"
,
pid
);
procfs_
=
buffer
;
}
bool
is_stale
()
{
return
inode_
!=
getinode_
();
}
void
reset
()
{
inode_
=
getinode_
();
}
};
class
ProcSyms
:
SymbolCache
{
struct
Symbol
{
Symbol
(
const
char
*
name
,
uint64_t
start
,
uint64_t
size
,
int
flags
=
0
)
:
name
(
name
),
start
(
start
),
size
(
size
),
flags
(
flags
)
{}
std
::
string
name
;
uint64_t
start
;
uint64_t
size
;
int
flags
;
};
struct
Module
{
Module
(
const
char
*
name
,
uint64_t
start
,
uint64_t
end
)
:
name_
(
name
),
start_
(
start
),
end_
(
end
)
{}
std
::
string
name_
;
uint64_t
start_
;
uint64_t
end_
;
std
::
vector
<
Symbol
>
syms_
;
void
load_sym_table
();
bool
decode_sym
(
uint64_t
addr
,
struct
bcc_symbol
*
sym
);
bool
is_so
()
{
return
strstr
(
name_
.
c_str
(),
".so"
)
!=
nullptr
;
}
static
int
_add_symbol
(
const
char
*
symname
,
uint64_t
start
,
uint64_t
end
,
int
flags
,
void
*
p
);
};
int
pid_
;
std
::
vector
<
Module
>
modules_
;
ProcStat
procstat_
;
static
void
_add_module
(
const
char
*
,
uint64_t
,
uint64_t
,
void
*
);
public:
ProcSyms
(
int
pid
);
virtual
void
refresh
();
virtual
bool
resolve_addr
(
uint64_t
addr
,
struct
bcc_symbol
*
sym
);
virtual
bool
resolve_name
(
const
char
*
name
,
uint64_t
*
addr
);
};
ProcSyms
::
ProcSyms
(
int
pid
)
:
pid_
(
pid
),
procstat_
(
pid
)
{
refresh
();
}
void
ProcSyms
::
refresh
()
{
...
...
@@ -165,10 +92,11 @@ void ProcSyms::refresh() {
procstat_
.
reset
();
}
void
ProcSyms
::
_add_module
(
const
char
*
modname
,
uint64_t
start
,
uint64_t
end
,
int
ProcSyms
::
_add_module
(
const
char
*
modname
,
uint64_t
start
,
uint64_t
end
,
void
*
payload
)
{
ProcSyms
*
ps
=
static_cast
<
ProcSyms
*>
(
payload
);
ps
->
modules_
.
emplace_back
(
modname
,
start
,
end
);
return
0
;
}
bool
ProcSyms
::
resolve_addr
(
uint64_t
addr
,
struct
bcc_symbol
*
sym
)
{
...
...
@@ -181,13 +109,20 @@ bool ProcSyms::resolve_addr(uint64_t addr, struct bcc_symbol *sym) {
for
(
Module
&
mod
:
modules_
)
{
if
(
addr
>=
mod
.
start_
&&
addr
<=
mod
.
end_
)
return
mod
.
decode_sym
(
addr
,
sym
);
return
mod
.
find_addr
(
addr
,
sym
);
}
return
false
;
}
bool
ProcSyms
::
resolve_name
(
const
char
*
name
,
uint64_t
*
addr
)
{
*
addr
=
0x0
;
bool
ProcSyms
::
resolve_name
(
const
char
*
module
,
const
char
*
name
,
uint64_t
*
addr
)
{
if
(
procstat_
.
is_stale
())
refresh
();
for
(
Module
&
mod
:
modules_
)
{
if
(
mod
.
name_
==
module
)
return
mod
.
find_name
(
name
,
addr
);
}
return
false
;
}
...
...
@@ -198,6 +133,10 @@ int ProcSyms::Module::_add_symbol(const char *symname, uint64_t start,
return
0
;
}
bool
ProcSyms
::
Module
::
is_so
()
const
{
return
strstr
(
name_
.
c_str
(),
".so"
)
!=
nullptr
;
}
void
ProcSyms
::
Module
::
load_sym_table
()
{
if
(
syms_
.
size
())
return
;
...
...
@@ -205,7 +144,19 @@ void ProcSyms::Module::load_sym_table() {
bcc_elf_foreach_sym
(
name_
.
c_str
(),
_add_symbol
,
this
);
}
bool
ProcSyms
::
Module
::
decode_sym
(
uint64_t
addr
,
struct
bcc_symbol
*
sym
)
{
bool
ProcSyms
::
Module
::
find_name
(
const
char
*
symname
,
uint64_t
*
addr
)
{
load_sym_table
();
for
(
Symbol
&
s
:
syms_
)
{
if
(
s
.
name
==
symname
)
{
*
addr
=
is_so
()
?
start_
+
s
.
start
:
s
.
start
;
return
true
;
}
}
return
false
;
}
bool
ProcSyms
::
Module
::
find_addr
(
uint64_t
addr
,
struct
bcc_symbol
*
sym
)
{
uint64_t
offset
=
is_so
()
?
(
addr
-
start_
)
:
addr
;
load_sym_table
();
...
...
@@ -240,7 +191,7 @@ int bcc_symcache_resolve(void *resolver, uint64_t addr,
int
bcc_symcache_resolve_name
(
void
*
resolver
,
const
char
*
name
,
uint64_t
*
addr
)
{
SymbolCache
*
cache
=
static_cast
<
SymbolCache
*>
(
resolver
);
return
cache
->
resolve_name
(
name
,
addr
)
?
0
:
-
1
;
return
cache
->
resolve_name
(
n
ullptr
,
n
ame
,
addr
)
?
0
:
-
1
;
}
void
bcc_symcache_refresh
(
void
*
resolver
)
{
...
...
@@ -251,6 +202,7 @@ void bcc_symcache_refresh(void *resolver) {
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
;
...
...
@@ -258,6 +210,10 @@ static int _find_sym(const char *symname, uint64_t addr, uint64_t end,
return
0
;
}
int
bcc_find_symbol_addr
(
struct
bcc_symbol
*
sym
)
{
return
bcc_elf_foreach_sym
(
sym
->
module
,
_find_sym
,
sym
);
}
int
bcc_resolve_symname
(
const
char
*
module
,
const
char
*
symname
,
const
uint64_t
addr
,
struct
bcc_symbol
*
sym
)
{
uint64_t
load_addr
;
...
...
@@ -286,8 +242,10 @@ int bcc_resolve_symname(const char *module, const char *symname,
sym
->
name
=
symname
;
sym
->
offset
=
addr
;
if
(
sym
->
name
&&
sym
->
offset
==
0x0
)
bcc_elf_foreach_sym
(
sym
->
module
,
_find_sym
,
sym
);
if
(
sym
->
name
&&
sym
->
offset
==
0x0
)
{
if
(
bcc_find_symbol_addr
(
sym
)
<
0
)
return
-
1
;
}
if
(
sym
->
offset
==
0x0
)
return
-
1
;
...
...
src/cc/bcc_syms.h
View file @
48501550
...
...
@@ -20,6 +20,8 @@
extern
"C"
{
#endif
#include <stdint.h>
struct
bcc_symbol
{
const
char
*
name
;
const
char
*
module
;
...
...
@@ -31,6 +33,7 @@ int bcc_symcache_resolve(void *symcache, uint64_t addr, struct bcc_symbol *sym);
int
bcc_symcache_resolve_name
(
void
*
resolver
,
const
char
*
name
,
uint64_t
*
addr
);
void
bcc_symcache_refresh
(
void
*
resolver
);
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
);
#ifdef __cplusplus
...
...
src/cc/syms.h
0 → 100644
View file @
48501550
/*
* Copyright (c) 2016 GitHub, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <algorithm>
#include <string>
#include <unordered_map>
#include <vector>
#include <sys/types.h>
class
ProcStat
{
std
::
string
procfs_
;
ino_t
inode_
;
ino_t
getinode_
();
public:
ProcStat
(
int
pid
);
bool
is_stale
()
{
return
inode_
!=
getinode_
();
}
void
reset
()
{
inode_
=
getinode_
();
}
};
class
SymbolCache
{
public:
virtual
void
refresh
()
=
0
;
virtual
bool
resolve_addr
(
uint64_t
addr
,
struct
bcc_symbol
*
sym
)
=
0
;
virtual
bool
resolve_name
(
const
char
*
module
,
const
char
*
name
,
uint64_t
*
addr
)
=
0
;
};
class
KSyms
:
SymbolCache
{
struct
Symbol
{
Symbol
(
const
char
*
name
,
uint64_t
addr
)
:
name
(
name
),
addr
(
addr
)
{}
std
::
string
name
;
uint64_t
addr
;
bool
operator
<
(
const
Symbol
&
rhs
)
const
{
return
addr
<
rhs
.
addr
;
}
};
std
::
vector
<
Symbol
>
syms_
;
std
::
unordered_map
<
std
::
string
,
uint64_t
>
symnames_
;
static
void
_add_symbol
(
const
char
*
,
uint64_t
,
void
*
);
public:
virtual
bool
resolve_addr
(
uint64_t
addr
,
struct
bcc_symbol
*
sym
);
virtual
bool
resolve_name
(
const
char
*
unused
,
const
char
*
name
,
uint64_t
*
addr
);
virtual
void
refresh
();
};
class
ProcSyms
:
SymbolCache
{
struct
Symbol
{
Symbol
(
const
char
*
name
,
uint64_t
start
,
uint64_t
size
,
int
flags
=
0
)
:
name
(
name
),
start
(
start
),
size
(
size
),
flags
(
flags
)
{}
std
::
string
name
;
uint64_t
start
;
uint64_t
size
;
int
flags
;
};
struct
Module
{
Module
(
const
char
*
name
,
uint64_t
start
,
uint64_t
end
)
:
name_
(
name
),
start_
(
start
),
end_
(
end
)
{}
std
::
string
name_
;
uint64_t
start_
;
uint64_t
end_
;
std
::
vector
<
Symbol
>
syms_
;
void
load_sym_table
();
bool
find_addr
(
uint64_t
addr
,
struct
bcc_symbol
*
sym
);
bool
find_name
(
const
char
*
symname
,
uint64_t
*
addr
);
bool
is_so
()
const
;
static
int
_add_symbol
(
const
char
*
symname
,
uint64_t
start
,
uint64_t
end
,
int
flags
,
void
*
p
);
};
int
pid_
;
std
::
vector
<
Module
>
modules_
;
ProcStat
procstat_
;
static
int
_add_module
(
const
char
*
,
uint64_t
,
uint64_t
,
void
*
);
public:
ProcSyms
(
int
pid
);
virtual
void
refresh
();
virtual
bool
resolve_addr
(
uint64_t
addr
,
struct
bcc_symbol
*
sym
);
virtual
bool
resolve_name
(
const
char
*
module
,
const
char
*
name
,
uint64_t
*
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