ruby-static-tracing 0.0.12 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/ruby-static-tracing/lib/deps-extconf.rb +1 -1
- data/ext/ruby-static-tracing/lib/libstapsdt/Makefile +76 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/example/demo.c +42 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/src/asm/libstapsdt-x86_64.s +14 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/src/dynamic-symbols.c +41 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/src/dynamic-symbols.h +34 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/src/errors.c +30 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/src/errors.h +8 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/src/hash-table.c +27 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/src/hash-table.h +3 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/src/libstapsdt.c +258 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/src/libstapsdt.h +67 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/src/sdtnote.c +176 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/src/sdtnote.h +46 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/src/section.c +30 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/src/section.h +21 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/src/shared-lib.c +563 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/src/shared-lib.h +46 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/src/string-table.c +67 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/src/string-table.h +28 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/src/util.c +12 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/src/util.h +6 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/tests/test-errors.c +77 -0
- data/ext/ruby-static-tracing/lib/libstapsdt/tests/test-memory-leaks.c +25 -0
- data/ext/ruby-static-tracing/lib/libusdt/Makefile +168 -0
- data/ext/ruby-static-tracing/lib/libusdt/test_mem_usage.c +77 -0
- data/ext/ruby-static-tracing/lib/libusdt/test_usdt.c +87 -0
- data/ext/ruby-static-tracing/lib/libusdt/usdt.c +321 -0
- data/ext/ruby-static-tracing/lib/libusdt/usdt.h +65 -0
- data/ext/ruby-static-tracing/lib/libusdt/usdt_dof.c +126 -0
- data/ext/ruby-static-tracing/lib/libusdt/usdt_dof_file.c +290 -0
- data/ext/ruby-static-tracing/lib/libusdt/usdt_dof_sections.c +180 -0
- data/ext/ruby-static-tracing/lib/libusdt/usdt_internal.h +107 -0
- data/ext/ruby-static-tracing/lib/libusdt/usdt_probe.c +133 -0
- data/ext/ruby-static-tracing/lib/libusdt/usdt_tracepoints_i386.s +69 -0
- data/ext/ruby-static-tracing/lib/libusdt/usdt_tracepoints_x86_64.s +123 -0
- data/lib/ruby-static-tracing/version.rb +1 -1
- metadata +38 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c9f06dac9e5b53283124140623a3677c85d32730f390716d7b2385fb20fbed4
|
4
|
+
data.tar.gz: daa93d708d1e42075fa5cb3043d2aabefac3bd9fd42161defd8481a0fb7d60fa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b742bc905d5ff7b8bad1b5d5fd1561b349ab2480c242402e93983f9b7fd6c0f5a1ff97055fb35be15ce80bad3db3f9d4b50596d04474f5f54aa7b52401932b2b
|
7
|
+
data.tar.gz: d4f394274ac8a1d763913ed4ec57fd20f321f9dbe153b8eb87c321a3d6e2204c14a184e5952e8a66b0f45a9588c49fe33f4a4ee3d9183463d42431c4f6e1c0e4
|
@@ -12,7 +12,7 @@ if StaticTracing::Platform.linux?
|
|
12
12
|
# and "trick" extconf into thinking it's just another .so
|
13
13
|
File.write "Makefile", <<MAKEFILE
|
14
14
|
all:
|
15
|
-
cd #{File.join(BASE_DIR, 'libstapsdt')} && make
|
15
|
+
cd #{File.join(BASE_DIR, 'libstapsdt')} && make CFLAGS_EXTRA=-DLIBSTAPSDT_MEMORY_BACKED_FD
|
16
16
|
touch deps.so # HACK
|
17
17
|
cp #{File.join(BASE_DIR, 'libstapsdt', 'out/libstapsdt.so.0')} #{LIB_DIR}
|
18
18
|
cd #{LIB_DIR} && ln -sf libstapsdt.so.0 libstapsdt.so
|
@@ -0,0 +1,76 @@
|
|
1
|
+
|
2
|
+
CC=gcc
|
3
|
+
CFLAGS= -std=gnu11 $(CFLAGS_EXTRA)
|
4
|
+
LDFLAGS=-lelf -ldl -Wl,-z,noexecstack
|
5
|
+
VERSION=0.1.0
|
6
|
+
|
7
|
+
PREFIX=/usr
|
8
|
+
|
9
|
+
OBJECTS = $(patsubst src/%.c, build/lib/%.o, $(wildcard src/*.c))
|
10
|
+
HEADERS = $(wildcard src/*.h)
|
11
|
+
|
12
|
+
SOLINK = libstapsdt.so
|
13
|
+
SONAME = libstapsdt.so.0
|
14
|
+
|
15
|
+
all: out/libstapsdt.a out/$(SONAME)
|
16
|
+
|
17
|
+
install:
|
18
|
+
mkdir -p $(DESTDIR)$(PREFIX)/lib
|
19
|
+
mkdir -p $(DESTDIR)$(PREFIX)/include
|
20
|
+
cp out/$(SONAME) $(DESTDIR)$(PREFIX)/lib/$(SONAME)
|
21
|
+
cp src/libstapsdt.h $(DESTDIR)$(PREFIX)/include/
|
22
|
+
ln -s $(DESTDIR)$(PREFIX)/lib/$(SONAME) $(DESTDIR)$(PREFIX)/lib/$(SOLINK)
|
23
|
+
|
24
|
+
uninstall:
|
25
|
+
rm -f $(DESTDIR)$(PREFIX)/lib/$(SONAME)
|
26
|
+
rm -f $(DESTDIR)$(PREFIX)/lib/$(SOLINK)
|
27
|
+
rm -f $(DESTDIR)$(PREFIX)/include/libstapsdt.h
|
28
|
+
|
29
|
+
build/lib/libstapsdt-x86_64.o: src/asm/libstapsdt-x86_64.s
|
30
|
+
mkdir -p build
|
31
|
+
$(CC) $(CFLAGS) -fPIC -c $^ -o $@
|
32
|
+
|
33
|
+
build/lib/%.o: src/%.c $(HEADERS)
|
34
|
+
mkdir -p build/lib/
|
35
|
+
$(CC) $(CFLAGS) -fPIC -c $< -o $@
|
36
|
+
|
37
|
+
out/libstapsdt.a: $(OBJECTS) build/lib/libstapsdt-x86_64.o
|
38
|
+
mkdir -p out
|
39
|
+
ar rcs $@ $^
|
40
|
+
|
41
|
+
out/$(SONAME): $(OBJECTS) build/lib/libstapsdt-x86_64.o
|
42
|
+
mkdir -p out
|
43
|
+
$(CC) $(CFLAGS) -shared -Wl,-soname=$(SONAME) -o $@ $^ $(LDFLAGS)
|
44
|
+
|
45
|
+
demo: all example/demo.c
|
46
|
+
$(CC) $(CFLAGS) example/demo.c out/libstapsdt.a -o demo -Isrc/ $(LDFLAGS)
|
47
|
+
|
48
|
+
test: all
|
49
|
+
make -C ./tests/
|
50
|
+
|
51
|
+
clean:
|
52
|
+
rm -rf build/*
|
53
|
+
rm -rf out/*
|
54
|
+
make clean -C ./tests/
|
55
|
+
|
56
|
+
lint:
|
57
|
+
clang-tidy src/*.h src/*.c -- -Isrc/
|
58
|
+
|
59
|
+
format:
|
60
|
+
clang-tidy src/*.h src/*.c -fix -- -Isrc/
|
61
|
+
|
62
|
+
docs:
|
63
|
+
make -C ./docs/ html
|
64
|
+
|
65
|
+
docs-server:
|
66
|
+
cd docs/_build/html; python3 -m http.server;
|
67
|
+
|
68
|
+
deb-pkg-setup:
|
69
|
+
mkdir -p dist/libstapsdt-$(VERSION)/;
|
70
|
+
git archive HEAD | gzip > dist/libstapsdt-$(VERSION).tar.gz;
|
71
|
+
tar xvzf dist/libstapsdt-$(VERSION).tar.gz -C dist/libstapsdt-$(VERSION)/;
|
72
|
+
cd dist/libstapsdt-$(VERSION); dh_make -l -c mit -y -f ../libstapsdt-$(VERSION).tar.gz;
|
73
|
+
rm -rf dist/libstapsdt-$(VERSION)/debian/*.ex dist/libstapsdt-$(VERSION)/debian/*.EX dist/libstapsdt-$(VERSION)/debian/README.*
|
74
|
+
|
75
|
+
|
76
|
+
.PHONY: all clear lint format build-tests docs install uninstall deb-pkg-setup
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <stdlib.h>
|
3
|
+
#include <unistd.h>
|
4
|
+
#include <libstapsdt.h>
|
5
|
+
|
6
|
+
int main( int argc, char *argv[] ) {
|
7
|
+
SDTProvider_t *provider;
|
8
|
+
SDTProbe_t **probes;
|
9
|
+
int probesCount = 0;
|
10
|
+
unsigned long long i=0;
|
11
|
+
int j=0;
|
12
|
+
|
13
|
+
if(argc < 3) {
|
14
|
+
printf("usage: demo PROVIDER PROBE\n");
|
15
|
+
return -1;
|
16
|
+
}
|
17
|
+
|
18
|
+
probesCount = argc - 2;
|
19
|
+
probes = calloc(sizeof(SDTProvider_t *), probesCount);
|
20
|
+
|
21
|
+
provider = providerInit(argv[1]);
|
22
|
+
for (int idx = 0; idx < (probesCount); idx++) {
|
23
|
+
probes[idx] = providerAddProbe(provider, argv[idx + 2], 2, uint64, int64);
|
24
|
+
}
|
25
|
+
|
26
|
+
if(providerLoad(provider) == -1) {
|
27
|
+
printf("Something went wrong: %s\n", provider->error);
|
28
|
+
return -1;
|
29
|
+
}
|
30
|
+
|
31
|
+
while(1) {
|
32
|
+
printf("Firing probes...\n");
|
33
|
+
for (int idx = 0; idx < probesCount; idx++) {
|
34
|
+
printf("Firing probe [%d]...\n", idx);
|
35
|
+
probeFire(probes[idx], i++, j--);
|
36
|
+
}
|
37
|
+
printf("Probe fired!\n");
|
38
|
+
sleep(3);
|
39
|
+
}
|
40
|
+
|
41
|
+
return 0;
|
42
|
+
}
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#include "dynamic-symbols.h"
|
2
|
+
#include "string-table.h"
|
3
|
+
#include <libelf.h>
|
4
|
+
|
5
|
+
DynamicSymbolTable *dynamicSymbolTableInit(StringTable *dynamicString) {
|
6
|
+
DynamicSymbolTable *dynSymTab =
|
7
|
+
(DynamicSymbolTable *)calloc(sizeof(DynamicSymbolTable), 1);
|
8
|
+
|
9
|
+
dynSymTab->stringTable = dynamicString;
|
10
|
+
|
11
|
+
dynSymTab->bssStart.string = stringTableAdd(dynamicString, "__bss_start");
|
12
|
+
dynSymTab->eData.string = stringTableAdd(dynamicString, "_edata");
|
13
|
+
dynSymTab->end.string = stringTableAdd(dynamicString, "_end");
|
14
|
+
|
15
|
+
dynSymTab->count = 0;
|
16
|
+
dynSymTab->symbols = NULL;
|
17
|
+
|
18
|
+
return dynSymTab;
|
19
|
+
}
|
20
|
+
|
21
|
+
DynamicSymbol *dynamicSymbolTableAdd(DynamicSymbolTable *table,
|
22
|
+
char *symbolName) {
|
23
|
+
DynamicSymbolList *symbol = (DynamicSymbolList *)calloc(sizeof(DynamicSymbolList), 1);
|
24
|
+
|
25
|
+
symbol->symbol.string = stringTableAdd(table->stringTable, symbolName);
|
26
|
+
|
27
|
+
symbol->next = table->symbols;
|
28
|
+
table->symbols = symbol;
|
29
|
+
table->count += 1;
|
30
|
+
|
31
|
+
return &(symbol->symbol);
|
32
|
+
}
|
33
|
+
|
34
|
+
void dynamicSymbolTableFree(DynamicSymbolTable *table) {
|
35
|
+
DynamicSymbolList *node=NULL, *next=NULL;
|
36
|
+
for(node=table->symbols; node!=NULL; node=next) {
|
37
|
+
next=node->next;
|
38
|
+
free(node);
|
39
|
+
}
|
40
|
+
free(table);
|
41
|
+
}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#ifndef _DYNAMIC_SYMBOLS_
|
2
|
+
#define _DYNAMIC_SYMBOLS_
|
3
|
+
|
4
|
+
#include "string-table.h"
|
5
|
+
#include <libelf.h>
|
6
|
+
|
7
|
+
typedef struct {
|
8
|
+
StringTableNode *string;
|
9
|
+
Elf64_Sym *symbol;
|
10
|
+
} DynamicSymbol;
|
11
|
+
|
12
|
+
typedef struct DynamicSymbolList_ {
|
13
|
+
DynamicSymbol symbol;
|
14
|
+
struct DynamicSymbolList_ *next;
|
15
|
+
} DynamicSymbolList;
|
16
|
+
|
17
|
+
typedef struct {
|
18
|
+
StringTable *stringTable;
|
19
|
+
|
20
|
+
DynamicSymbol bssStart;
|
21
|
+
DynamicSymbol eData;
|
22
|
+
DynamicSymbol end;
|
23
|
+
|
24
|
+
size_t count;
|
25
|
+
DynamicSymbolList *symbols;
|
26
|
+
} DynamicSymbolTable;
|
27
|
+
|
28
|
+
DynamicSymbolTable *dynamicSymbolTableInit(StringTable *dynamicString);
|
29
|
+
DynamicSymbol *dynamicSymbolTableAdd(DynamicSymbolTable *table,
|
30
|
+
char *symbolName);
|
31
|
+
|
32
|
+
void dynamicSymbolTableFree(DynamicSymbolTable *table);
|
33
|
+
|
34
|
+
#endif
|
@@ -0,0 +1,30 @@
|
|
1
|
+
|
2
|
+
#include <stdarg.h>
|
3
|
+
#define _GNU_SOURCE
|
4
|
+
#include <stdlib.h>
|
5
|
+
#include <stdio.h>
|
6
|
+
|
7
|
+
#include "errors.h"
|
8
|
+
|
9
|
+
const char *sdtErrors[] = {
|
10
|
+
"failed to create Elf shared library for provider '%s'",
|
11
|
+
"failed to create temporary file",
|
12
|
+
"failed to open shared library '%s': %s",
|
13
|
+
"failed to load symbol '%s' for shared library '%s': %s",
|
14
|
+
"failed to close shared library '%s' for provider '%s': %s",
|
15
|
+
};
|
16
|
+
|
17
|
+
void sdtSetError(SDTProvider_t *provider, SDTError_t error, ...) {
|
18
|
+
va_list argp;
|
19
|
+
|
20
|
+
if(provider->error != NULL) {
|
21
|
+
free(provider->error);
|
22
|
+
provider->error = NULL;
|
23
|
+
provider->errno = noError;
|
24
|
+
}
|
25
|
+
|
26
|
+
va_start(argp, error);
|
27
|
+
provider->errno = error;
|
28
|
+
(void)vasprintf(&provider->error, sdtErrors[error], argp);
|
29
|
+
va_end(argp);
|
30
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include "dynamic-symbols.h"
|
3
|
+
|
4
|
+
size_t hashTableFromSymbolTable(DynamicSymbolTable *table, uint32_t **hashTable) {
|
5
|
+
DynamicSymbolList *current;
|
6
|
+
uint32_t nBuckets = table->count + 3, // + 3, to count bss, end, and eData symbols
|
7
|
+
nChains = table->count + 3;
|
8
|
+
size_t hashTableSize = (nBuckets + nChains + 2);
|
9
|
+
|
10
|
+
uint32_t *hashTable_ = (uint32_t *)calloc(sizeof(uint32_t), hashTableSize);
|
11
|
+
uint32_t *buckets = &(hashTable_[2]);
|
12
|
+
uint32_t *chains = &(buckets[nBuckets]);
|
13
|
+
int idx, stringIdx=2;
|
14
|
+
|
15
|
+
hashTable_[0] = nBuckets;
|
16
|
+
hashTable_[1] = nChains;
|
17
|
+
|
18
|
+
for(current=table->symbols; current!=NULL; current=current->next) {
|
19
|
+
idx = elf_hash(current->symbol.string->str) % nBuckets;
|
20
|
+
chains[stringIdx] = buckets[idx];
|
21
|
+
buckets[idx] = stringIdx;
|
22
|
+
stringIdx++;
|
23
|
+
}
|
24
|
+
|
25
|
+
*hashTable = hashTable_;
|
26
|
+
return hashTableSize * sizeof(uint32_t);
|
27
|
+
}
|
@@ -0,0 +1,258 @@
|
|
1
|
+
#include <dlfcn.h>
|
2
|
+
#include <err.h>
|
3
|
+
#include <fcntl.h>
|
4
|
+
#include <libelf.h>
|
5
|
+
#include <limits.h>
|
6
|
+
#include <stdarg.h>
|
7
|
+
#include <stdio.h>
|
8
|
+
#include <stdlib.h>
|
9
|
+
#include <string.h>
|
10
|
+
#include <sys/types.h>
|
11
|
+
#include <unistd.h>
|
12
|
+
|
13
|
+
#include "dynamic-symbols.h"
|
14
|
+
#include "sdtnote.h"
|
15
|
+
#include "section.h"
|
16
|
+
#include "string-table.h"
|
17
|
+
#include "shared-lib.h"
|
18
|
+
#include "util.h"
|
19
|
+
#include "libstapsdt.h"
|
20
|
+
#include "errors.h"
|
21
|
+
|
22
|
+
#ifdef LIBSTAPSDT_MEMORY_BACKED_FD
|
23
|
+
#include <linux/memfd.h>
|
24
|
+
#include <sys/mman.h>
|
25
|
+
#include <sys/syscall.h>
|
26
|
+
|
27
|
+
#define F_SEAL_SEAL 0x0001 /* prevent further seals from being set */
|
28
|
+
|
29
|
+
// Note that linux must be 3.17 or greater to support this
|
30
|
+
static inline int memfd_create(const char *name, unsigned int flags) {
|
31
|
+
return syscall(__NR_memfd_create, name, flags);
|
32
|
+
}
|
33
|
+
#endif
|
34
|
+
|
35
|
+
int createSharedLibrary(int fd, SDTProvider_t *provider) {
|
36
|
+
DynElf *dynElf = dynElfInit(fd);
|
37
|
+
|
38
|
+
for(SDTProbeList_t *node=provider->probes; node != NULL; node = node->next) {
|
39
|
+
dynElfAddProbe(dynElf, &(node->probe));
|
40
|
+
}
|
41
|
+
|
42
|
+
if(dynElfSave(dynElf) == -1) {
|
43
|
+
sdtSetError(provider, elfCreationError, provider->name);
|
44
|
+
return -1;
|
45
|
+
}
|
46
|
+
|
47
|
+
dynElfClose(dynElf);
|
48
|
+
|
49
|
+
return 0;
|
50
|
+
}
|
51
|
+
|
52
|
+
SDTProvider_t *providerInit(const char *name) {
|
53
|
+
SDTProvider_t *provider = (SDTProvider_t *) calloc(sizeof(SDTProvider_t), 1);
|
54
|
+
provider->error = NULL;
|
55
|
+
provider->errno = noError;
|
56
|
+
provider->probes = NULL;
|
57
|
+
provider->_handle = NULL;
|
58
|
+
provider->_filename = NULL;
|
59
|
+
provider->_memfd = -1;
|
60
|
+
|
61
|
+
provider->name = (char *) calloc(sizeof(char), strlen(name) + 1);
|
62
|
+
memcpy(provider->name, name, sizeof(char) * strlen(name) + 1);
|
63
|
+
|
64
|
+
return provider;
|
65
|
+
}
|
66
|
+
|
67
|
+
SDTProbe_t *providerAddProbe(SDTProvider_t *provider, const char *name, int argCount, ...) {
|
68
|
+
int i;
|
69
|
+
va_list vl;
|
70
|
+
ArgType_t arg;
|
71
|
+
va_start(vl, argCount);
|
72
|
+
|
73
|
+
SDTProbeList_t *probeList = (SDTProbeList_t *) calloc(sizeof(SDTProbeList_t), 1);
|
74
|
+
probeList->probe._fire = NULL;
|
75
|
+
|
76
|
+
probeList->probe.name = (char *) calloc(sizeof(char), strlen(name) + 1);
|
77
|
+
memcpy(probeList->probe.name, name, sizeof(char) * strlen(name) + 1);
|
78
|
+
|
79
|
+
probeList->next = provider->probes;
|
80
|
+
provider->probes = probeList;
|
81
|
+
|
82
|
+
probeList->probe.argCount = argCount;
|
83
|
+
|
84
|
+
for(i=0; i < argCount; i++) {
|
85
|
+
arg = va_arg(vl, ArgType_t);
|
86
|
+
probeList->probe.argFmt[i] = arg;
|
87
|
+
}
|
88
|
+
|
89
|
+
for(; i<MAX_ARGUMENTS; i++) {
|
90
|
+
probeList->probe.argFmt[i] = noarg;
|
91
|
+
}
|
92
|
+
|
93
|
+
probeList->probe.provider = provider;
|
94
|
+
|
95
|
+
return &(probeList->probe);
|
96
|
+
}
|
97
|
+
|
98
|
+
static char *tempElfPath(int *fd, const char *name) {
|
99
|
+
char *filename = NULL;
|
100
|
+
|
101
|
+
#ifdef LIBSTAPSDT_MEMORY_BACKED_FD
|
102
|
+
char path_buffer[PATH_MAX + 1];
|
103
|
+
snprintf(path_buffer, (PATH_MAX + 1), "libstapsdt:%s", name);
|
104
|
+
|
105
|
+
*fd = memfd_create(path_buffer, F_SEAL_SEAL);
|
106
|
+
if (*fd < 0)
|
107
|
+
return NULL;
|
108
|
+
snprintf(path_buffer, (PATH_MAX + 1), "/proc/%d/fd/%d", getpid(), *fd);
|
109
|
+
|
110
|
+
filename = calloc(sizeof(char), (strlen(path_buffer) + 1));
|
111
|
+
strcpy(filename, path_buffer);
|
112
|
+
#else
|
113
|
+
filename = calloc(sizeof(char), strlen("/tmp/-XXXXXX.so") + strlen(name) + 1);
|
114
|
+
|
115
|
+
sprintf(filename, "/tmp/%s-XXXXXX.so", name);
|
116
|
+
|
117
|
+
if ((*fd = mkstemps(filename, 3)) < 0) {
|
118
|
+
free(filename);
|
119
|
+
return NULL;
|
120
|
+
}
|
121
|
+
#endif
|
122
|
+
return filename;
|
123
|
+
}
|
124
|
+
|
125
|
+
int providerLoad(SDTProvider_t *provider) {
|
126
|
+
int fd;
|
127
|
+
void *fireProbe;
|
128
|
+
char *error;
|
129
|
+
|
130
|
+
provider->_filename = tempElfPath(&fd, provider->name);
|
131
|
+
#ifdef LIBSTAPSDT_MEMORY_BACKED_FD
|
132
|
+
provider->_memfd = fd;
|
133
|
+
#endif
|
134
|
+
if (provider->_filename == NULL) {
|
135
|
+
sdtSetError(provider, tmpCreationError);
|
136
|
+
return -1;
|
137
|
+
}
|
138
|
+
|
139
|
+
if(createSharedLibrary(fd, provider) != 0) {
|
140
|
+
(void)close(fd);
|
141
|
+
return -1;
|
142
|
+
}
|
143
|
+
|
144
|
+
if (provider->_memfd == -1)
|
145
|
+
(void)close(fd);
|
146
|
+
|
147
|
+
provider->_handle = dlopen(provider->_filename, RTLD_LAZY);
|
148
|
+
if (!provider->_handle) {
|
149
|
+
sdtSetError(provider, sharedLibraryOpenError, provider->_filename,
|
150
|
+
dlerror());
|
151
|
+
return -1;
|
152
|
+
}
|
153
|
+
|
154
|
+
for(SDTProbeList_t *node=provider->probes; node != NULL; node = node->next) {
|
155
|
+
fireProbe = dlsym(provider->_handle, node->probe.name);
|
156
|
+
|
157
|
+
// TODO (mmarchini) handle errors better when a symbol fails to load
|
158
|
+
if ((error = dlerror()) != NULL) {
|
159
|
+
sdtSetError(provider, sharedLibraryOpenError, provider->_filename,
|
160
|
+
node->probe.name, error);
|
161
|
+
return -1;
|
162
|
+
}
|
163
|
+
|
164
|
+
node->probe._fire = fireProbe;
|
165
|
+
}
|
166
|
+
|
167
|
+
|
168
|
+
return 0;
|
169
|
+
}
|
170
|
+
|
171
|
+
int providerUnload(SDTProvider_t *provider) {
|
172
|
+
if(provider->_handle == NULL) {
|
173
|
+
return 0;
|
174
|
+
}
|
175
|
+
if(dlclose(provider->_handle) != 0) {
|
176
|
+
sdtSetError(provider, sharedLibraryCloseError, provider->_filename, provider->name, dlerror());
|
177
|
+
return -1;
|
178
|
+
}
|
179
|
+
provider->_handle = NULL;
|
180
|
+
|
181
|
+
for(SDTProbeList_t *node=provider->probes; node != NULL; node = node->next) {
|
182
|
+
node->probe._fire = NULL;
|
183
|
+
}
|
184
|
+
|
185
|
+
if (provider->_memfd > 0) {
|
186
|
+
(void)close(provider->_memfd);
|
187
|
+
provider->_memfd = -1;
|
188
|
+
} else {
|
189
|
+
unlink(provider->_filename);
|
190
|
+
}
|
191
|
+
free(provider->_filename);
|
192
|
+
|
193
|
+
return 0;
|
194
|
+
}
|
195
|
+
|
196
|
+
void probeFire(SDTProbe_t *probe, ...) {
|
197
|
+
if(probe->_fire == NULL) {
|
198
|
+
return;
|
199
|
+
}
|
200
|
+
va_list vl;
|
201
|
+
va_start(vl, probe);
|
202
|
+
uint64_t arg[6] = {0};
|
203
|
+
for(int i=0; i < probe->argCount; i++) {
|
204
|
+
arg[i] = va_arg(vl, uint64_t);
|
205
|
+
}
|
206
|
+
|
207
|
+
switch(probe->argCount) {
|
208
|
+
case 0:
|
209
|
+
((void (*)())probe->_fire) ();
|
210
|
+
return;
|
211
|
+
case 1:
|
212
|
+
((void (*)())probe->_fire) (arg[0]);
|
213
|
+
return;
|
214
|
+
case 2:
|
215
|
+
((void (*)())probe->_fire) (arg[0], arg[1]);
|
216
|
+
return;
|
217
|
+
case 3:
|
218
|
+
((void (*)())probe->_fire) (arg[0], arg[1], arg[2]);
|
219
|
+
return;
|
220
|
+
case 4:
|
221
|
+
((void (*)())probe->_fire) (arg[0], arg[1], arg[2], arg[3]);
|
222
|
+
return;
|
223
|
+
case 5:
|
224
|
+
((void (*)())probe->_fire) (arg[0], arg[1], arg[2], arg[3], arg[4]);
|
225
|
+
return;
|
226
|
+
case 6:
|
227
|
+
((void (*)())probe->_fire) (arg[0], arg[1], arg[2], arg[3], arg[4], arg[5]);
|
228
|
+
return;
|
229
|
+
default:
|
230
|
+
((void (*)())probe->_fire) ();
|
231
|
+
return;
|
232
|
+
}
|
233
|
+
}
|
234
|
+
|
235
|
+
int probeIsEnabled(SDTProbe_t *probe) {
|
236
|
+
if(probe->_fire == NULL) {
|
237
|
+
return 0;
|
238
|
+
}
|
239
|
+
if(((*(char *)probe->_fire) & 0x90) == 0x90) {
|
240
|
+
return 0;
|
241
|
+
}
|
242
|
+
return 1;
|
243
|
+
}
|
244
|
+
|
245
|
+
void providerDestroy(SDTProvider_t *provider) {
|
246
|
+
SDTProbeList_t *node=NULL, *next=NULL;
|
247
|
+
|
248
|
+
for(node=provider->probes; node!=NULL; node=next) {
|
249
|
+
free(node->probe.name);
|
250
|
+
next=node->next;
|
251
|
+
free(node);
|
252
|
+
}
|
253
|
+
free(provider->name);
|
254
|
+
if(provider->error != NULL) {
|
255
|
+
free(provider->error);
|
256
|
+
}
|
257
|
+
free(provider);
|
258
|
+
}
|