Skip to content

Commit b84bd80

Browse files
committed
Expose fdtransfer, jattach and jcmd and support lib-prefix
1 parent 18d00da commit b84bd80

File tree

2 files changed

+77
-15
lines changed

2 files changed

+77
-15
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ build/%:
118118
mkdir -p $@
119119

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

124124
PROFILER_FLAGS=-static-libgcc

src/launcher/main.cpp

Lines changed: 76 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ static const char USAGE_STRING[] =
5151
" list list profiling events supported by the target JVM\n"
5252
" collect collect profile for the specified period of time\n"
5353
" and then stop (default action)\n"
54+
" fdtransfer start fdtransfer to serve perf requests on behalf of profiled process\n"
55+
" jattach invoke jattach directly; requires --jattach-cmd,\n"
56+
" ignores all arguments except --lib-prefix\n"
57+
"\n"
5458
"Options:\n"
5559
" -e event profiling event: cpu|alloc|lock|cache-misses etc.\n"
5660
" -d duration run profiling for <duration> seconds\n"
@@ -87,6 +91,12 @@ static const char USAGE_STRING[] =
8791
" --jfrsync config synchronize profiler with JFR recording\n"
8892
" --fdtransfer use fdtransfer to serve perf requests\n"
8993
" from the non-privileged target\n"
94+
" --fd-path string use specified path for fdtransfer to listen at\n"
95+
" --jattach-cmd string\n"
96+
" arguments to use with jattach action\n"
97+
" -L|--lib-prefix string\n"
98+
" path prefix to prepend to shared lib\n"
99+
" --fd-path string socket path for fdtransfer to bind to\n"
90100
"\n"
91101
"<pid> is a numeric process ID of the target JVM\n"
92102
" or 'jps' keyword to find running JVM automatically\n"
@@ -170,6 +180,10 @@ class String {
170180
return strcmp(_str, other._str) == 0;
171181
}
172182

183+
bool operator!=(const String& other) const {
184+
return strcmp(_str, other._str) != 0;
185+
}
186+
173187
String& operator<<(const char* tail) {
174188
size_t len = strlen(_str);
175189
_str = (char*)realloc(_str, len + strlen(tail) + 1);
@@ -205,7 +219,9 @@ class String {
205219

206220

207221
static String action = "collect";
208-
static const String empty;
222+
static const String kEmpty;
223+
static const String kJattachLoad = "load";
224+
static const String kJattachJcmd = "jcmd";
209225
static String file, logfile, output, params, format, fdtransfer, libpath;
210226
static bool use_tmp_file = false;
211227
static int duration = 60;
@@ -333,38 +349,51 @@ static void run_fdtransfer(int pid, String& fdtransfer) {
333349
}
334350
}
335351

336-
static void run_jattach(int pid, String& cmd) {
352+
static void run_jattach(int pid, const String& verb, String& cmd) {
337353
pid_t child = fork();
338354
if (child == -1) {
339355
error("fork failed", errno);
340356
}
341357

342358
if (child == 0) {
343-
const char* argv[] = {"load", libpath.str(), libpath.str()[0] == '/' ? "true" : "false", cmd.str()};
344-
exit(jattach(pid, 4, argv));
359+
const char** argv;
360+
int argc;
361+
int ret;
362+
String pidstr;
363+
pidstr << pid;
364+
if (verb == kJattachLoad) {
365+
const char* args[] = {kJattachLoad.str(), libpath.str(), libpath.str()[0] == '/' ? "true" : "false", cmd.str()};
366+
ret = jattach(pid, 4, args);
367+
} else if (verb == kJattachJcmd) {
368+
const char* args[] = {kJattachJcmd.str(), cmd.str()};
369+
ret = jattach(pid, 2, args);
370+
}
371+
exit(ret);
345372
} else {
346373
int ret = wait_for_exit(child);
347374
if (ret != 0) {
348375
if (WEXITSTATUS(ret) == 255) {
349376
fprintf(stderr, "Target JVM failed to load %s\n", libpath.str());
350377
}
351-
print_file(logfile, STDERR_FILENO);
378+
if (logfile != kEmpty) print_file(logfile, STDERR_FILENO);
352379
exit(WEXITSTATUS(ret));
353380
}
354381

355-
print_file(logfile, STDERR_FILENO);
382+
if (logfile != kEmpty) print_file(logfile, STDERR_FILENO);
356383
if (use_tmp_file) print_file(file, STDOUT_FILENO);
357384
}
358385
}
359386

360387

361388
int main(int argc, const char** argv) {
362389
Args args(argc, argv);
390+
String jattach_cmd;
363391
while (args.hasNext()) {
364392
String arg = args.next();
365393

366394
if (arg == "start" || arg == "resume" || arg == "stop" || arg == "dump" || arg == "check" ||
367-
arg == "status" || arg == "meminfo" || arg == "list" || arg == "collect") {
395+
arg == "status" || arg == "meminfo" || arg == "list" || arg == "collect" ||
396+
arg == "fdtransfer" || arg == "jattach" || arg == "jcmd") {
368397
action = arg;
369398

370399
} else if (arg == "-h" || arg == "--help") {
@@ -457,12 +486,20 @@ int main(int argc, const char** argv) {
457486
params << "," << (arg.str() + 2) << "=" << args.next();
458487
if (action == "collect") action = "start";
459488

489+
} else if (arg == "--fd-path") {
490+
fdtransfer = String(args.next());
491+
460492
} else if (arg == "--fdtransfer") {
461493
char buf[64];
462-
snprintf(buf, sizeof(buf), "@async-profiler-%d-%08x", getpid(), (unsigned int)time_micros());
463-
fdtransfer = buf;
494+
if (fdtransfer == kEmpty) {
495+
snprintf(buf, sizeof(buf), "@async-profiler-%d-%08x", getpid(), (unsigned int)time_micros());
496+
fdtransfer = buf;
497+
}
464498
params << ",fdtransfer=" << fdtransfer;
465499

500+
} else if (arg == "--jattach-cmd") {
501+
jattach_cmd = String(args.next());
502+
466503
} else if (arg.str()[0] >= '0' && arg.str()[0] <= '9' && pid == 0) {
467504
pid = atoi(arg.str());
468505

@@ -489,14 +526,19 @@ int main(int argc, const char** argv) {
489526
return 1;
490527
}
491528

492-
setup_output_files(pid);
493-
if (libpath == empty) {
529+
if (jattach_cmd == kEmpty) {
530+
setup_output_files(pid);
531+
} else if (params != kEmpty) {
532+
fprintf(stderr, "Warning: --jattach-cmd was given, these parameters will be ignored: %s\n", params.str());
533+
}
534+
535+
if (libpath == kEmpty) {
494536
setup_lib_path();
495537
}
496538

497539
if (action == "collect") {
498540
run_fdtransfer(pid, fdtransfer);
499-
run_jattach(pid, String("start,file=") << file << "," << output << format << params << ",log=" << logfile);
541+
run_jattach(pid, kJattachLoad, String("start,file=") << file << "," << output << format << params << ",log=" << logfile);
500542

501543
fprintf(stderr, "Profiling for %d seconds\n", duration);
502544
end_time = time_micros() + duration * 1000000ULL;
@@ -514,10 +556,30 @@ int main(int argc, const char** argv) {
514556
signal(SIGINT, SIG_DFL);
515557
fprintf(stderr, "Done\n");
516558

517-
run_jattach(pid, String("stop,file=") << file << "," << output << format << ",log=" << logfile);
559+
run_jattach(pid, kJattachLoad, String("stop,file=") << file << "," << output << format << ",log=" << logfile);
560+
} else if (action == "fdtransfer") {
561+
if (params != kEmpty) {
562+
fprintf(stderr, "Warning: action fdtransfer was given, these parameters will be ignored: %s\n", params.str());
563+
}
564+
run_fdtransfer(pid, fdtransfer);
565+
566+
} else if (action == "jattach") {
567+
if (jattach_cmd == kEmpty) {
568+
fprintf(stderr, "Action jattach was given, missing required --jattach-cmd argument\n");
569+
return 1;
570+
}
571+
run_jattach(pid, kJattachLoad, jattach_cmd);
572+
573+
} else if (action == "jcmd") {
574+
if (jattach_cmd == kEmpty) {
575+
fprintf(stderr, "Action jcmd was given, missing required --jattach-cmd argument\n");
576+
return 1;
577+
}
578+
run_jattach(pid, kJattachJcmd, jattach_cmd);
579+
518580
} else {
519581
if (action == "start" || action == "resume") run_fdtransfer(pid, fdtransfer);
520-
run_jattach(pid, String(action) << ",file=" << file << "," << output << format << params << ",log=" << logfile);
582+
run_jattach(pid, kJattachLoad, String(action) << ",file=" << file << "," << output << format << params << ",log=" << logfile);
521583
}
522584

523585
return 0;

0 commit comments

Comments
 (0)