Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add recycle flag which allows resetting timeout timer #6

Open
wants to merge 33 commits into
base: async-profiler-granulate
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
13e835e
Remove the "Profiling started" message
Jongy May 31, 2021
e16fad0
Remove the "Profiling stopped" message
Jongy Jun 5, 2021
0c25728
Compile statically with libstdc++
Jongy Jul 12, 2021
fca73de
Build jattach statically
Jongy Jul 12, 2021
f8f77fd
Build fdtransfer statically
Jongy Oct 4, 2021
ab6e1de
Compile statically with libgcc
Jongy Nov 29, 2021
ae5daf1
Fix -static-* args passed only in non-MERGE case :(
Jongy Apr 14, 2022
c8c72a1
Close standard streams after forking in fdtransfer
Jongy Jul 12, 2022
49080a2
-static-libstdc++ only on musl
Jongy Aug 30, 2022
f4d874c
Convert frame name format to 'function (DSO)' for LIB style (#2)
marcin-ol Oct 26, 2022
bb06e23
Add accept timeout as 3rd parameter of fdtransfer
Jongy Nov 18, 2022
faaabf8
Use compat-glibc on x86_64 glibc
Jongy Nov 29, 2022
df5df4a
dump stats on stop
guybortnikov Nov 29, 2022
60cbc12
Do not try to parse mapped pseudofiles
apangin Dec 20, 2022
4938ce8
Add option to include method modifiers in frame name (#5)
mpozniak95 Mar 15, 2023
666a620
Add recycle flag which allows resetting timeout timer
marcin-ol Mar 23, 2023
d3a863a
Remove the "Profiling started" message
Jongy May 31, 2021
a0a9633
Remove the "Profiling stopped" message
Jongy Jun 5, 2021
f71df14
Compile statically with libstdc++
Jongy Jul 12, 2021
bf4337c
Compile statically with libgcc
Jongy Nov 29, 2021
8ebf525
Fix -static-* args passed only in non-MERGE case :(
Jongy Apr 14, 2022
98280ba
Close standard streams after forking in fdtransfer
Jongy Jul 12, 2022
87f9dff
-static-libstdc++ only on musl
Jongy Aug 30, 2022
99e87c8
Convert frame name format to 'function (DSO)' for LIB style (#2)
marcin-ol Oct 26, 2022
f83d0dc
Use compat-glibc on x86_64 glibc
Jongy Nov 29, 2022
6778799
dump stats on stop
guybortnikov Nov 29, 2022
1f31fdc
Add option to include method modifiers in frame name (#5)
mpozniak95 Mar 15, 2023
b3baf60
Export gProfiler-needed functionality from asprof (#7)
marcin-ol May 10, 2023
684098c
Merge remote-tracking branch 'origin/timeout-recycle' into new-timeou…
marcin-ol Jul 14, 2023
46a6883
Add reset trace functionality
marcin-ol Jul 19, 2023
7d2c6ab
Add dumpactive flag to verify dump is called when actively profiling
marcin-ol Jul 20, 2023
40b850a
Add includeln argument which includes method line number to frame (#8)
mpozniak95 Jul 25, 2023
0107623
Merge remote-tracking branch 'upstream/async-profiler-granulate' into…
marcin-ol Aug 2, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -118,15 +118,28 @@ build/%:
mkdir -p $@

build/$(LAUNCHER): src/launcher/* src/jattach/* src/fdtransfer.h
$(CC) $(CPPFLAGS) $(CFLAGS) -DPROFILER_VERSION=\"$(PROFILER_VERSION)\" -DSUPPRESS_OUTPUT -o $@ src/launcher/*.cpp src/jattach/*.c
$(CC) $(CPPFLAGS) $(CFLAGS) -static -DPROFILER_VERSION=\"$(PROFILER_VERSION)\" -o $@ src/launcher/*.cpp src/jattach/*.c
strip $@

PROFILER_FLAGS=-static-libgcc
ifeq ($(OS_TAG),linux-musl)
PROFILER_FLAGS+= -static-libstdc++
endif

# On x86_64 glibc (not musl), build against compat-glibc
# see https://centos.pkgs.org/7/centos-x86_64/compat-glibc-2.12-4.el7.centos.x86_64.rpm.html
ifneq ($(OS_TAG),linux-musl)
ifeq ($(ARCH),x86_64)
PROFILER_FLAGS+= -I /usr/lib/x86_64-redhat-linux6E/include -B /usr/lib/x86_64-redhat-linux6E/lib64/
endif
endif

build/$(LIB_PROFILER): $(SOURCES) $(HEADERS) $(RESOURCES) $(JAVA_HELPER_CLASSES)
ifeq ($(MERGE),true)
for f in src/*.cpp; do echo '#include "'$$f'"'; done |\
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -DPROFILER_VERSION=\"$(PROFILER_VERSION)\" $(INCLUDES) -fPIC -shared -o $@ -xc++ - $(LIBS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -DPROFILER_VERSION=\"$(PROFILER_VERSION)\" $(INCLUDES) -fPIC -shared $(PROFILER_FLAGS) -o $@ -xc++ - $(LIBS)
else
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -DPROFILER_VERSION=\"$(PROFILER_VERSION)\" $(INCLUDES) -fPIC -shared -o $@ $(SOURCES) $(LIBS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -DPROFILER_VERSION=\"$(PROFILER_VERSION)\" $(INCLUDES) -fPIC -shared $(PROFILER_FLAGS) -o $@ $(SOURCES) $(LIBS)
endif

build/$(API_JAR): $(API_SOURCES)
Expand All @@ -142,7 +155,7 @@ build/$(CONVERTER_JAR): $(CONVERTER_SOURCES) $(RESOURCES)
$(RM) -r build/converter

%.class: %.java
$(JAVAC) --source $(JAVA_TARGET) -target $(JAVA_TARGET) -Xlint:-options -g:none $^
$(JAVAC) -source $(JAVA_TARGET) -target $(JAVA_TARGET) -Xlint:-options -g:none $^

test: all
test/smoke-test.sh
Expand Down
27 changes: 27 additions & 0 deletions src/arguments.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ static const Multiplier UNIVERSAL[] = {{'n', 1}, {'u', 1000}, {'m', 1000000}, {'
// title=TITLE - FlameGraph title
// minwidth=PCT - FlameGraph minimum frame width in percent
// reverse - generate stack-reversed FlameGraph / Call tree
// includemm - inclue method modifiers
// recycle - recycle timeout timer (only: dump and status)
//
// It is possible to specify multiple dump options at the same time

Expand Down Expand Up @@ -364,6 +366,24 @@ Error Arguments::parse(const char* args) {
CASE("reverse")
_reverse = true;

CASE("meminfolog")
_log_meminfo_on_dump = true;

CASE("includemm")
_includemm = true;

CASE("includeln")
_includeln = true;

CASE("recycle")
_recycle = true;

CASE("resettrace")
_reset_trace = true;

CASE("dumpactive")
_dump_active = true;

DEFAULT()
if (_unknown_arg == NULL) _unknown_arg = arg;
}
Expand Down Expand Up @@ -391,6 +411,13 @@ Error Arguments::parse(const char* args) {
_action = ACTION_DUMP;
}

if (_recycle && _action != ACTION_DUMP && _action != ACTION_STATUS) {
return Error("Recycle argument only valid for actions: dump and status");
}
if (_recycle && _loop) {
return Error("Recycle argument doesn't support loop mode");
}

return Error::OK;
}

Expand Down
15 changes: 14 additions & 1 deletion src/arguments.h
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ class Arguments {
bool _sched;
bool _live;
bool _fdtransfer;
bool _includemm;
bool _includeln;
const char* _fdtransfer_path;
int _style;
CStack _cstack;
Expand All @@ -184,6 +186,11 @@ class Arguments {
const char* _title;
double _minwidth;
bool _reverse;
// Granulate Extra
bool _log_meminfo_on_dump;
bool _recycle;
bool _reset_trace;
bool _dump_active;

Arguments(bool persistent = false) :
_buf(NULL),
Expand Down Expand Up @@ -230,7 +237,13 @@ class Arguments {
_end(NULL),
_title(NULL),
_minwidth(0),
_reverse(false) {
_reverse(false),
_log_meminfo_on_dump(false),
_includemm(false),
_includeln(false),
_recycle(false),
_reset_trace(false),
_dump_active(false) {
}

~Arguments();
Expand Down
8 changes: 7 additions & 1 deletion src/codeCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ size_t NativeFunc::usedMemory(const char* name) {

CodeCache::CodeCache(const char* name, short lib_index, const void* min_address, const void* max_address) {
_name = NativeFunc::create(name, -1);
char *tmp = (char*)malloc(strlen(name) + 3);
snprintf(tmp, strlen(name) + 3, "(%s)", name);
_lib_symbol = NativeFunc::create(tmp, -1);
free(tmp);
_lib_index = lib_index;
_min_address = min_address;
_max_address = max_address;
Expand All @@ -63,6 +67,7 @@ CodeCache::~CodeCache() {
for (int i = 0; i < _count; i++) {
NativeFunc::destroy(_blobs[i]._name);
}
NativeFunc::destroy(_lib_symbol);
NativeFunc::destroy(_name);
delete[] _blobs;
free(_dwarf_table);
Expand Down Expand Up @@ -153,7 +158,8 @@ const char* CodeCache::binarySearch(const void* address) {
if (low > 0 && (_blobs[low - 1]._start == _blobs[low - 1]._end || _blobs[low - 1]._end == address)) {
return _blobs[low - 1]._name;
}
return _name;

return _lib_symbol;
}

const void* CodeCache::findSymbol(const char* name) {
Expand Down
1 change: 1 addition & 0 deletions src/codeCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ class FrameDesc;
class CodeCache {
protected:
char* _name;
char* _lib_symbol;
short _lib_index;
const void* _min_address;
const void* _max_address;
Expand Down
45 changes: 42 additions & 3 deletions src/frameName.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,24 @@ static inline bool isDigit(char c) {
}


// Based on: https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#:~:text=Table%C2%A04.5.%C2%A0Method%20access%20and%20property%20flags
// Good practice order from: https://checkstyle.sourceforge.io/config_modifier.html#ModifierOrder
const static std::pair<int, std::string> access_flags [] = {
std::make_pair(0x0001, "public"),
std::make_pair(0x0002, "private"),
std::make_pair(0x0004, "protected"),
std::make_pair(0x0400, "abstract"),
std::make_pair(0x0008, "static"),
std::make_pair(0x0010, "final"),
std::make_pair(0x0020, "synchronized"),
std::make_pair(0x0100, "native"),
std::make_pair(0x0800, "strict"),
std::make_pair(0x0040, "bridge"),
std::make_pair(0x0080, "varargs"),
std::make_pair(0x1000, "synthetic"),
};


Matcher::Matcher(const char* pattern) {
if (pattern[0] == '*') {
_type = MATCH_ENDS_WITH;
Expand Down Expand Up @@ -95,7 +113,8 @@ FrameName::FrameName(Arguments& args, int style, int epoch, Mutex& thread_names_
{
// Require printf to use standard C format regardless of system locale
_saved_locale = uselocale(newlocale(LC_NUMERIC_MASK, "C", (locale_t)0));

_includemm = args._includemm;
_includeln = args._includeln;
buildFilter(_include, args._buf, args._include);
buildFilter(_exclude, args._buf, args._exclude);

Expand Down Expand Up @@ -133,7 +152,7 @@ const char* FrameName::decodeNativeSymbol(const char* name) {
char* demangled = Demangle::demangle(name);
if (demangled != NULL) {
if (lib_name != NULL) {
_str.assign(lib_name).append("`").append(demangled);
_str.assign(demangled).append(" (").append(lib_name).append(")");
} else {
_str.assign(demangled);
}
Expand All @@ -143,7 +162,7 @@ const char* FrameName::decodeNativeSymbol(const char* name) {
}

if (lib_name != NULL) {
return _str.assign(lib_name).append("`").append(name).c_str();
return _str.assign(name).append(" (").append(lib_name).append(")").c_str();
} else {
return name;
}
Expand All @@ -167,6 +186,9 @@ void FrameName::javaMethodName(jmethodID method) {
char* class_name = NULL;
char* method_name = NULL;
char* method_sig = NULL;
jvmtiLineNumberEntry* line_number_table = NULL;
jint entry_count = 0;
jint modifiers = 0;

jvmtiEnv* jvmti = VM::jvmti();
jvmtiError err;
Expand All @@ -176,7 +198,24 @@ void FrameName::javaMethodName(jmethodID method) {
(err = jvmti->GetClassSignature(method_class, &class_name, NULL)) == 0) {
// Trim 'L' and ';' off the class descriptor like 'Ljava/lang/Object;'
javaClassName(class_name + 1, strlen(class_name) - 2, _style);
if (_includemm) {
jvmti->GetMethodModifiers(method, &modifiers);
std::string modifiers_to_append = "";
for (int i=0; i<(sizeof(access_flags) / sizeof(access_flags[0])); i++) {
if (modifiers & access_flags[i].first) {
modifiers_to_append.append(access_flags[i].second + " ");
}
}
_str.insert(0, modifiers_to_append);
}
_str.append(".").append(method_name);
if (_includeln) {
if (jvmti->GetLineNumberTable(method, &entry_count, &line_number_table) == 0) {
char buf[32];
sprintf(buf, ":%d", line_number_table[0].line_number);
_str.append(buf);
}
}
if (_style & STYLE_SIGNATURES) {
if (_style & STYLE_NO_SEMICOLON) {
for (char* s = method_sig; *s; s++) {
Expand Down
2 changes: 2 additions & 0 deletions src/frameName.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ class FrameName {
Mutex& _thread_names_lock;
ThreadMap& _thread_names;
locale_t _saved_locale;
bool _includemm;
bool _includeln;

void buildFilter(std::vector<Matcher>& vector, const char* base, int offset);
const char* decodeNativeSymbol(const char* name);
Expand Down
4 changes: 2 additions & 2 deletions src/launcher/fdtransferServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class FdTransferServer {
public:
static bool supported() { return true; }

static bool runOnce(int pid, const char *path);
static bool runOnce(int pid, const char *path, unsigned int timeout);
static bool runLoop(const char *path);
};

Expand All @@ -46,7 +46,7 @@ class FdTransferServer {
public:
static bool supported() { return false; }

static bool runOnce(int pid, const char *path) { return false; }
static bool runOnce(int pid, const char *path, unsigned int timeout) { return false; }
static bool runLoop(const char *path) { return false; }
};

Expand Down
7 changes: 5 additions & 2 deletions src/launcher/fdtransferServer_linux.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ bool FdTransferServer::sendFd(int fd, struct fd_response *resp, size_t resp_size
return true;
}

bool FdTransferServer::runOnce(int pid, const char *path) {
bool FdTransferServer::runOnce(int pid, const char *path, unsigned int timeout) {
// get its nspid prior to moving to its PID namespace.
int nspid;
uid_t target_uid;
Expand All @@ -287,7 +287,7 @@ bool FdTransferServer::runOnce(int pid, const char *path) {
}
}

if (!bindServer(&sun, addrlen, 30)) {
if (!bindServer(&sun, addrlen, timeout)) {
return false;
}

Expand All @@ -298,6 +298,9 @@ bool FdTransferServer::runOnce(int pid, const char *path) {

// CLONE_NEWPID affects children only - so we fork here.
if (fork() == 0) {
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
return acceptPeer(&nspid) && serveRequests(nspid);
} else {
// Exit now, let our caller continue.
Expand Down
Loading