Skip to content

Commit 470f89b

Browse files
committed
DTV info detection improvements per feedback
- Move DTVInfo struct definition into C - Make DTVInfo struct members mirror TSDInfo names - Rename IsPotentialTSDDSO
1 parent 3af371a commit 470f89b

File tree

7 files changed

+55
-47
lines changed

7 files changed

+55
-47
lines changed

libc/libc.go

Lines changed: 25 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import (
1515
)
1616

1717
type TSDInfo = support.TSDInfo
18+
type DTVInfo = support.DTVInfo
1819

1920
// LibcInfo contains introspection information extracted from the C-library
2021
type LibcInfo struct {
@@ -24,15 +25,31 @@ type LibcInfo struct {
2425
DTVInfo DTVInfo
2526
}
2627

28+
var (
29+
// regex for the libc
30+
libcRegex = regexp.MustCompile(`.*/(ld-musl|ld-linux|libc|libpthread)([-.].*)?\.so`)
31+
)
2732

28-
// TODO comment
29-
type DTVInfo struct {
30-
// Offset is the offset of DTV from FS base (or from thread pointer)
31-
Offset int64
32-
// EntryWidth is the size of each DTV entry in bytes
33-
EntryWidth uint32
34-
// Indirect is 0 if DTV is at FS+offset, 1 if at [FS+0]+offset
35-
Indirect uint8
33+
// IsPotentialLibcDSO determines if the DSO filename potentially contains libc code
34+
func IsPotentialLibcDSO(filename string) bool {
35+
return libcRegex.MatchString(filename)
36+
}
37+
38+
func ExtractLibcInfo(ef *pfelf.File) (*LibcInfo, error) {
39+
tsdinfo, err := extractTSDInfo(ef)
40+
if err != nil {
41+
return nil, err
42+
}
43+
44+
dtvinfo, err := extractDTVInfo(ef)
45+
if err != nil {
46+
return &LibcInfo{}, err
47+
}
48+
49+
return &LibcInfo{
50+
TSDInfo: tsdinfo,
51+
DTVInfo: dtvinfo,
52+
}, nil
3653
}
3754

3855
// This code analyzes the C-library provided POSIX defined function which is used
@@ -80,33 +97,6 @@ type DTVInfo struct {
8097
//
8198
// Reading the value is basically "return self->specific_1stblock[key].data;"
8299

83-
var (
84-
// regex for the libc
85-
libcRegex = regexp.MustCompile(`.*/(ld-musl|libc|libpthread)([-.].*)?\.so`)
86-
)
87-
88-
// IsPotentialTSDDSO determines if the DSO filename potentially contains pthread code
89-
func IsPotentialTSDDSO(filename string) bool {
90-
return libcRegex.MatchString(filename)
91-
}
92-
93-
func ExtractLibcInfo(ef *pfelf.File) (*LibcInfo, error) {
94-
tsdinfo, err := extractTSDInfo(ef)
95-
if err != nil {
96-
return nil, err
97-
}
98-
99-
dtvinfo, err := extractDTVInfo(ef)
100-
if err != nil {
101-
return &LibcInfo{}, err
102-
}
103-
104-
return &LibcInfo{
105-
TSDInfo: tsdinfo,
106-
DTVInfo: dtvinfo,
107-
}, nil
108-
}
109-
110100
// extractTSDInfo extracts the introspection data for pthread thread specific data.
111101
func extractTSDInfo(ef *pfelf.File) (TSDInfo, error) {
112102
_, code, err := ef.SymbolData("__pthread_getspecific", 2048)

libc/libc_aarch64.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,8 +332,8 @@ func extractDTVInfoARM(code []byte) (DTVInfo, error) {
332332
}
333333

334334
return DTVInfo{
335-
Offset: dtvOffset,
336-
EntryWidth: entryWidth,
335+
Offset: int16(dtvOffset),
336+
Multiplier: uint8(entryWidth),
337337
Indirect: 1,
338338
}, nil
339339
}

libc/libc_x86.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ func extractDTVInfoX86(code []byte) (DTVInfo, error) {
120120

121121
if result.Match(expected) {
122122
return DTVInfo{
123-
Offset: int64(dtvOffset.CapturedValue()),
124-
EntryWidth: uint32(entryWidth.CapturedValue()),
123+
Offset: int16(dtvOffset.CapturedValue()),
124+
Multiplier: uint8(entryWidth.CapturedValue()),
125125
Indirect: 0,
126126
}, nil
127127
}
@@ -143,8 +143,8 @@ func extractDTVInfoX86(code []byte) (DTVInfo, error) {
143143

144144
if result.Match(expected) {
145145
return DTVInfo{
146-
Offset: int64(dtvOffset.CapturedValue()),
147-
EntryWidth: uint32(entryWidth.CapturedValue()),
146+
Offset: int16(dtvOffset.CapturedValue()),
147+
Multiplier: uint8(entryWidth.CapturedValue()),
148148
Indirect: 1,
149149
}, nil
150150
}
@@ -162,8 +162,8 @@ func extractDTVInfoX86(code []byte) (DTVInfo, error) {
162162

163163
if result.Match(expected) {
164164
return DTVInfo{
165-
Offset: int64(dtvOffset.CapturedValue()),
166-
EntryWidth: uint32(entryWidth.CapturedValue()),
165+
Offset: int16(dtvOffset.CapturedValue()),
166+
Multiplier: uint8(entryWidth.CapturedValue()),
167167
Indirect: 1,
168168
}, nil
169169
}
@@ -182,8 +182,8 @@ func extractDTVInfoX86(code []byte) (DTVInfo, error) {
182182

183183
if result.Match(expected) {
184184
return DTVInfo{
185-
Offset: int64(dtvOffset.CapturedValue()),
186-
EntryWidth: uint32(entryWidth.CapturedValue()),
185+
Offset: int16(dtvOffset.CapturedValue()),
186+
Multiplier: uint8(entryWidth.CapturedValue()),
187187
Indirect: 1,
188188
}, nil
189189
}

processmanager/execinfomanager/manager.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,8 @@ func (mgr *ExecutableInfoManager) AddOrIncRef(fileID host.FileID,
194194
intervalData = synthesizeIntervalData(ef)
195195
}
196196

197-
// Also gather TSD info if applicable.
198-
if libc.IsPotentialTSDDSO(elfRef.FileName()) {
197+
// Also gather Libc info if applicable.
198+
if libc.IsPotentialLibcDSO(elfRef.FileName()) {
199199
if ef, errx := elfRef.GetELF(); errx == nil {
200200
libcInfo, _ = libc.ExtractLibcInfo(ef)
201201
}

support/ebpf/types.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,18 @@ typedef struct TSDInfo {
406406
u8 indirect;
407407
} TSDInfo;
408408

409+
// DTVInfo contains data needed to read Thread Local Storage (TLS) values, which
410+
// are located using the Dynamic Thread Vector (DTV)
411+
typedef struct DTVInfo {
412+
// Offset is the offset of DTV from FS base (or from thread pointer)
413+
s16 offset;
414+
// Multiplier is the size of each DTV entry in bytes
415+
// Typically 8 bytes on 64bit musl and 16 bytes on 64bit glibc
416+
u8 multiplier;
417+
// Indirect is 0 if DTV is at FS+offset, 1 if at [FS+0]+offset
418+
u8 indirect;
419+
} DTVInfo;
420+
409421
// DotnetProcInfo is a container for the data needed to build stack trace for a dotnet process.
410422
typedef struct DotnetProcInfo {
411423
u32 version;

support/types.go

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

support/types_def.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ type StackDeltaPageInfo C.StackDeltaPageInfo
119119
type StackDeltaPageKey C.StackDeltaPageKey
120120
type SystemAnalysis C.SystemAnalysis
121121
type TSDInfo C.TSDInfo
122+
type DTVInfo C.DTVInfo
122123
type Trace C.Trace
123124
type UnwindInfo C.UnwindInfo
124125

0 commit comments

Comments
 (0)