00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "xdprof.h"
00033 #include <jni.h>
00034
00035 JVMPI_Interface *jvmpi_interface;
00036 JavaVM* GlobalJVM;
00037
00038 inline static string GetSelfInfo()
00039 {
00040 ostringstream oss;
00041
00042
00043
00044
00045
00046
00047 oss << _getpid();
00048 oss << ends;
00049 string s = oss.str();
00050
00051 return s.substr(0, s.length() - 1);
00052 }
00053
00054 inline void Leave(string s)
00055 {
00056 cout << flush << s << endl;
00057 CALL(ProfilerExit)((jlong)0);
00058 }
00059
00061 static string GetUsage()
00062 {
00063 string usage = "\nXDPROF Usage:\n\n-Xrunxdprof:server=HOSTNAME,port=PORT,refresh=REFRESH[,description=OPTIONAL_DESCRIPTION,hotspot=true]";
00064 usage = usage + "\n" + "where ";
00065 usage = usage + "\n" + "\t" + "server=HOSTNAME is the machine running the DPROF server";
00066 usage = usage + "\n" + "\t" + "port=PORT is the port number of the DPROF server";
00067 usage = usage + "\n" + "\t" + "refresh=REFRESH is the time to refresh in milliseconds (1000 = 1 sec)";
00068 usage = usage + "\n" + "" + "Optional arguments: ";
00069 usage = usage + "\n" + "\t" + "description=OPTIONAL_DESCRIPTION is a string (without spaces) describing this VM";
00070 usage = usage + "\n" + "\t" + "hotspot=true is set when the HotSpot (non-classic) VM is used (this is not guaranteed to work)";
00071 usage = usage + "\n" + "\nOther runtime flags that should be passed to the VM:";
00072 usage = usage + "\n" + "\t" + "-classic -Xdebug -Xnoagent ";
00073 usage = usage + "\n";
00074 usage = usage + "\nThe final command line will then look like: \n\n" +
00075 "java -classic -Xdebug -Xnoagent -Xrunxdprof:server=localhost,port=1337,refresh=199,description=MyDescription c\n\n";
00076 return usage;
00077 }
00078
00079
00083 static string getToken(const string & entire, const string & token )
00084 {
00085 if (entire.size() == 0 || token.size() == 0)
00086 return "";
00087 const string foo = "," + entire + ",";
00088 string::size_type i = foo.find("," + token + "=");
00089 if (i == string::npos)
00090 return "";
00091
00092 int j = i + token.size() + 2;
00093 int k = foo.find(",", j);
00094 return foo.substr(j, k - j);
00095 }
00096
00097
00098
00099 extern "C"
00100 {
00101 #pragma warning(disable:4100)
00102 JNIEXPORT jint JNICALL JVM_OnLoad(JavaVM *jvm, char *options, void *reserved)
00103 {
00104 if ((jvm->GetEnv((void **)&jvmpi_interface, JVMPI_VERSION_1)) < 0)
00105 {
00106 fprintf(stderr, "error in obtaining jvmpi interface pointer");
00107 fflush(stderr);
00108 return JNI_ERR;
00109 }
00110
00111 GlobalJVM = jvm;
00112
00113
00114 jvmpi_interface->NotifyEvent = NotifyEvent;
00115
00116
00117 InitializeMonitors();
00118
00119 CHECKEDCALL(EnableEvent(JVMPI_EVENT_JVM_INIT_DONE , NULL));
00120 CHECKEDCALL(EnableEvent(JVMPI_EVENT_JVM_SHUT_DOWN , NULL));
00121
00122 CHECKEDCALL(EnableEvent(JVMPI_EVENT_THREAD_START, NULL));
00123 CHECKEDCALL(EnableEvent(JVMPI_EVENT_THREAD_END, NULL));
00124
00125 CHECKEDCALL(EnableEvent(JVMPI_EVENT_CLASS_LOAD , NULL));
00126 CHECKEDCALL(EnableEvent(JVMPI_EVENT_CLASS_UNLOAD , NULL));
00127
00128
00129 CHECKEDCALL(EnableEvent(JVMPI_EVENT_OBJECT_ALLOC , NULL));
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146 string selfinfo = GetSelfInfo();
00147 string hostname = "localhost";
00148 long port = 1337;
00149 long refresh = 2000;
00150 HotSpot = false;
00151
00152 if (options != NULL)
00153 {
00154 string s(options);
00155 if (s == "help")
00156 {
00157 Leave(GetUsage());
00158 }
00159 hostname = getToken(s, "server");
00160 if (hostname == "")
00161 Leave("Invalid hostname.");
00162
00163 port = atoi(getToken(s, "port").c_str());
00164 if (port <= 0 || port > 65535)
00165 Leave("Bad port number " + getToken(s, "port"));
00166
00167 refresh = atoi(getToken(s, "refresh").c_str());
00168 if (refresh <= 0)
00169 Leave("Bad refresh number " + getToken(s, "refresh"));
00170
00171
00172 if (getToken(s, "description") != "")
00173 {
00174 selfinfo += ' ';
00175 selfinfo += getToken(s, "description");
00176 }
00177 else
00178 selfinfo += " none";
00179
00180 if (getToken(s, "hotspot") == "true")
00181 {
00182 HotSpot = true;
00183 }
00184
00185 debug("All options", s);
00186 }
00187 else
00188 {
00189 debug("Using defaults...");
00190 }
00191
00192 debug("Hostname: ", hostname);
00193 debug("Port: ", port);
00194 debug("Refresh: ", refresh);
00195 debug("SelfInfo: ", selfinfo);
00196 debug("HotSpot: ", HotSpot ? "true" : "false");
00197
00198 InitializeBackgroundThread(hostname, port, selfinfo, refresh);
00199
00200 return JNI_OK;
00201 }
00202 #pragma warning(default:4100)
00203 }