Trong đó, tác nhân java gắn với tín hiệu SIGQUIT. Tôi muốn tránh điều đó, bởi vì đó là tín hiệu tương tự mà JVM sử dụng để viết một chuỗi kết xuất tới stdout. Tôi muốn tránh sự trùng lặp đó.
Chỉ cần xoá đoạn sau đây từ mã của bạn
/* Set callbacks and enable event notifications */
memset(&callbacks, 0, sizeof(callbacks));
callbacks.DataDumpRequest = &dumpThreadInfo;
err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks));
CHECK_JVMTI_ERROR(jvmti, err);
err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE,JVMTI_EVENT_DATA_DUMP_REQUEST, NULL);
CHECK_JVMTI_ERROR(jvmti, err);
Tôi muốn thể đính kèm vào một tín hiệu khác nhau
Here is giấy, đó là một chút cũ, nhưng thông tin vẫn có liên quan.
Chỉ cần một mẫu như thế nào để làm một tín hiệu xử lý
import sun.misc.Signal;
import sun.misc.SignalHandler;
public class ThreadDumpSignalHandler implements SignalHandler {
private volatile SignalHandler old;
private ThreadDumpSignalHandler() {
}
public static void register(String sigName) {
ThreadDumpSignalHandler h = new ThreadDumpSignalHandler();
h.old = Signal.handle(new Signal(sigName), h)
}
public void handle(Signal sig) {
threadDump();
if(old != null && old != SIG_DFL && old != SIG_IGN) {
old.handle(sig);
}
}
// call your own threadDump native method.
// note that in the implementation of this method you are able to access jvmtiEnv from *gdata (see below)
private native void threadDump();
}
ThreadDumpSignalHandler.register("INT");
Trong số nguyên nhân bạn có thể viết xử lý tín hiệu hoàn toàn tự nhiên (xin lưu ý rằng tôi đã không kiểm tra nó, đây chỉ là một ý kiến cho rằng nên làm việc)
static sighandler_t old_handler;
static void thread_dump_handler(int signum) {
if(gdata && gdata->jvmti) {
... get thread dump
}
if(old_handler) {
old_handler(signum);
}
}
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved) {
old_handler = signal(SIGINT, thread_dump_handler);
...
}
hoặc tìm cách cho các đại lý để tạo ra một bãi chứa thread theo định kỳ.
Trong mẫu của bạn có toàn cầu * gdata
typedef struct {
/* JVMTI Environment */
jvmtiEnv *jvmti;
jboolean vm_is_started;
/* Data access Lock */
jrawMonitorID lock;
} GlobalAgentData;
static GlobalAgentData *gdata;
... do đó, chỉ cần có được jvmtiEnv từ đó bất cứ lúc nào bạn muốn (callbacks timer, vv)
Không ai trong số các sự kiện trong jvmtiEventCallbacks trông phù hợp (trừ khi bạn muốn sử dụng DataDumpRequestion, nhưng nếu bạn đã làm, bạn sẽ không bị yêu cầu ở đây :)). Có vẻ như bạn tốt nhất nên nhờ đại lý của bạn gọi trực tiếp 'GetStackTrace'. Có lý do nào bạn không thể làm điều đó? –
@ Paul-Hicks, Bạn có thể đăng một liên kết hoặc mã về cách tôi sẽ đính kèm vào jvm trong trường hợp này? – Ovesh
Bạn đặt dll đại lý hoặc .so trong đường dẫn của jvm -agentpath hoặc xác định nó như là một -agentlib. Hãy xem [câu trả lời này] (http://stackoverflow.com/a/173447/3195526) hoặc [trang giới thiệu của IBM] (http://publib.boulder.ibm.com/infocenter/realtime/v2r0/index. jsp? topic =% 2Fcom.ibm.rt.doc.20% 2Fdiag% 2Ftools% 2Fjvmti.html). Đây có phải là điều bạn muốn biết không? Tôi có nên biến câu trả lời này thành câu trả lời không? –