aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/symbolizer
diff options
context:
space:
mode:
authorJoey Jiao <joeyjiaojg@gmail.com>2021-03-02 09:31:32 +0800
committerDmitry Vyukov <dvyukov@google.com>2021-03-05 20:05:43 +0100
commit69a06ca2b532ff4021a43fdead4e2ac1452a44c0 (patch)
tree3ed7ff70026f51ff0a8f980b5967daeb30bcad71 /pkg/symbolizer
parent800618b02f4f840756eb4218603a313113f94f05 (diff)
all: add KernelModule cfg to show DLKM coverage
PC returned for dynamic loaded module (DLKM) is not parsed in coverage page. So the commit is to use DLKM modules' load address to restore the PC and show coverage data of DLKM. As the load address is written in cfg file, so kaslr needs to be disabled. And for linux target, load address is getting from /proc/modules during instance setup. For either manual or auto address setting case, name and path are needed in config kernel_modules, where name is module name on target. path is module unstripped object path on host. addr is decimal value of module load address on target. Example of config: "kernel_modules": [ { "name": "nf_nat", "path": "/usr/src/linux-source/net/netfilter/nf_nat.ko", "addr": 18446744072637911040 } ]
Diffstat (limited to 'pkg/symbolizer')
-rw-r--r--pkg/symbolizer/symbolizer.go14
-rw-r--r--pkg/symbolizer/symbolizer_test.go13
2 files changed, 17 insertions, 10 deletions
diff --git a/pkg/symbolizer/symbolizer.go b/pkg/symbolizer/symbolizer.go
index 96b62fb95..87342e750 100644
--- a/pkg/symbolizer/symbolizer.go
+++ b/pkg/symbolizer/symbolizer.go
@@ -23,6 +23,7 @@ type Symbolizer struct {
}
type Frame struct {
+ Module string
PC uint64
Func string
File string
@@ -43,15 +44,15 @@ func NewSymbolizer(target *targets.Target) *Symbolizer {
}
func (s *Symbolizer) Symbolize(bin string, pc uint64) ([]Frame, error) {
- return s.SymbolizeArray(bin, []uint64{pc})
+ return s.SymbolizeArray("kernel", bin, []uint64{pc})
}
-func (s *Symbolizer) SymbolizeArray(bin string, pcs []uint64) ([]Frame, error) {
+func (s *Symbolizer) SymbolizeArray(module, bin string, pcs []uint64) ([]Frame, error) {
sub, err := s.getSubprocess(bin)
if err != nil {
return nil, err
}
- return symbolize(sub.input, sub.scanner, pcs)
+ return symbolize(sub.input, sub.scanner, pcs, module)
}
func (s *Symbolizer) Close() {
@@ -100,7 +101,7 @@ func (s *Symbolizer) getSubprocess(bin string) (*subprocess, error) {
return sub, nil
}
-func symbolize(input *bufio.Writer, scanner *bufio.Scanner, pcs []uint64) ([]Frame, error) {
+func symbolize(input *bufio.Writer, scanner *bufio.Scanner, pcs []uint64, module string) ([]Frame, error) {
var frames []Frame
done := make(chan error, 1)
go func() {
@@ -116,7 +117,7 @@ func symbolize(input *bufio.Writer, scanner *bufio.Scanner, pcs []uint64) ([]Fra
}
for range pcs {
var frames1 []Frame
- frames1, err = parse(scanner)
+ frames1, err = parse(scanner, module)
if err != nil {
return
}
@@ -145,7 +146,7 @@ func symbolize(input *bufio.Writer, scanner *bufio.Scanner, pcs []uint64) ([]Fra
return frames, nil
}
-func parse(s *bufio.Scanner) ([]Frame, error) {
+func parse(s *bufio.Scanner, module string) ([]Frame, error) {
pc, err := strconv.ParseUint(s.Text(), 0, 64)
if err != nil {
return nil, fmt.Errorf("failed to parse pc '%v' in addr2line output: %v", s.Text(), err)
@@ -182,6 +183,7 @@ func parse(s *bufio.Scanner) ([]Frame, error) {
continue
}
frames = append(frames, Frame{
+ Module: module,
PC: pc,
Func: fn,
File: file,
diff --git a/pkg/symbolizer/symbolizer_test.go b/pkg/symbolizer/symbolizer_test.go
index 0bddb2f71..cdbef8e6c 100644
--- a/pkg/symbolizer/symbolizer_test.go
+++ b/pkg/symbolizer/symbolizer_test.go
@@ -25,6 +25,7 @@ func TestParse(t *testing.T) {
"mm/kasan/report.c:320\n",
[]Frame{
{
+ Module: "kernel",
PC: 0xffffffff8180a42e,
Func: "__asan_report_load2_noabort",
File: "mm/kasan/report.c",
@@ -42,6 +43,7 @@ func TestParse(t *testing.T) {
"mm/kasan/report.c:320\n",
[]Frame{
{
+ Module: "kernel",
PC: 0xffffffff8180a42d,
Func: "kasan_report",
File: "mm/kasan/report.c",
@@ -49,6 +51,7 @@ func TestParse(t *testing.T) {
Inline: true,
},
{
+ Module: "kernel",
PC: 0xffffffff8180a42d,
Func: "__asan_report_load2_noabort",
File: "mm/kasan/report.c",
@@ -64,6 +67,7 @@ func TestParse(t *testing.T) {
"drivers/video/console/fbcon.c:2750\n",
[]Frame{
{
+ Module: "kernel",
PC: 0xffffffff82fdbe0b,
Func: "fbcon_invert_region",
File: "drivers/video/console/fbcon.c",
@@ -93,6 +97,7 @@ func TestParse(t *testing.T) {
"fs/devpts/inode.c:588 (discriminator 3)\n",
[]Frame{
{
+ Module: "kernel",
PC: 0xffffffff81a2aff9,
Func: "devpts_get_priv",
File: "fs/devpts/inode.c",
@@ -153,7 +158,7 @@ func TestParse(t *testing.T) {
var allPCs []uint64
var allFrames []Frame
for _, addr := range addresses {
- frames, err := symbolize(input, scanner, []uint64{addr.pc})
+ frames, err := symbolize(input, scanner, []uint64{addr.pc}, "kernel")
if err != nil {
t.Fatalf("got error: %v", err)
}
@@ -166,11 +171,11 @@ func TestParse(t *testing.T) {
// Symbolize PCs in 2 groups.
for i := 0; i <= len(addresses); i++ {
- frames, err := symbolize(input, scanner, allPCs[:i])
+ frames, err := symbolize(input, scanner, allPCs[:i], "kernel")
if err != nil {
t.Fatalf("got error: %v", err)
}
- frames2, err := symbolize(input, scanner, allPCs[i:])
+ frames2, err := symbolize(input, scanner, allPCs[i:], "kernel")
if err != nil {
t.Fatalf("got error: %v", err)
}
@@ -185,7 +190,7 @@ func TestParse(t *testing.T) {
for i := range lots {
lots[i] = addresses[0].pc
}
- frames, err := symbolize(input, scanner, lots)
+ frames, err := symbolize(input, scanner, lots, "kernel")
if err != nil {
t.Fatalf("got error: %v", err)
}