【问题标题】:Starting JVM via JNI with remote debugging通过 JNI 启动 JVM 并进行远程调试
【发布时间】:2013-12-05 00:47:48
【问题描述】:

我有一个用 Java 编写的服务器,我们在本机代码下为其启动和停止 JVM。我遇到了特定于该环境的问题,因此我想在打开远程调试的情况下启动 JVM。

这是我的 JVM 选项:

char** vmargs = NULL;
int vmargc = 4;
{
   // Configure the VM Args for the JVM
   //Log( "vmargs: %d\n",vma-2);
   vmargs = new char*[vmargc];

   vmargs[0] = new char[1024];
   vmargs[1] = new char[1024];
   vmargs[2] = new char[1024];
   vmargs[3] = new char[1024];

   _snprintf_s(vmargs[0], 1024,_TRUNCATE, "-Djava.library.path=%s\\bin\\lib", root.c_str());        
   _snprintf_s(vmargs[1], 1024,_TRUNCATE, "-Djava.class.path=%s\\bin\\%s", root.c_str(), JarName);
   _snprintf_s(vmargs[2], 1024,_TRUNCATE, "-Xrs");
   _snprintf_s(vmargs[3], 1024,_TRUNCATE, "-Xdebug -Xrunjdwp:transport=dt_socket,address=8989,server=y,suspend=y");

    Log( "vmarg %d:%s.\n",0,vmargs[0]);
    Log( "vmarg %d:%s.\n",1,vmargs[1]);
    Log( "vmarg %d:%s.\n",2,vmargs[2]);
    Log( "vmarg %d:%s.\n",3,vmargs[3]);
}

如您所见,我使用的是“-Xdebug -Xrunjdwp:transport=dt_socket,address=8989,server=y,suspend=y”。这些选项通过以下方式输入 JVM:

int optNum = 0;
for (int g=0; g<vmargc; ++g) {
   options[optNum++].optionString = vmargs[g];
   Log("Added vmarg: %s\n", options[g].optionString);
}
vm_args.version = JNI_VERSION_1_4; //JNI Version 1.4 and above
vm_args.options = options;
vm_args.nOptions = optNum;
vm_args.ignoreUnrecognized = JNI_TRUE;

//Create the JVM
res = createJVM(&vm, (void **)&env, &vm_args);

不幸的是,JVM 既不等待调试器附加也不接受端口 8989 上的连接(连接被拒绝)。我尝试了其他端口,但似乎 JVM 忽略了我的选择。

JVM 正在正确启动服务器,我可以将客户端连接到它。

关于我做错了什么有什么想法吗?

【问题讨论】:

    标签: java java-native-interface remote-debugging


    【解决方案1】:

    想通了。每个参数都必须有其 char* 数组条目,否则会混淆 JVM。更正后的代码如下:

    char** vmargs = NULL;
    int vmargc = 5;
    {
        // Configure the VM Args for the JVM
        vmargs = new char*[vmargc];
    
        vmargs[0] = new char[1024];
        vmargs[1] = new char[1024];
        vmargs[2] = new char[1024];
        vmargs[3] = new char[1024];
        vmargs[4] = new char[1024];
    
        _snprintf_s(vmargs[0], 1024,_TRUNCATE, "-Djava.library.path=%s\\bin\\lib", root.c_str());       
       _snprintf_s(vmargs[1], 1024,_TRUNCATE, "-Djava.class.path=%s\\bin\\%s", root.c_str(), JarName);
       _snprintf_s(vmargs[2], 1024,_TRUNCATE, "-Xrs");
       _snprintf_s(vmargs[3], 1024,_TRUNCATE, "-Xdebug");
       _snprintf_s(vmargs[4], 1024,_TRUNCATE, "-Xrunjdwp:transport=dt_socket,address=8989,server=y,suspend=y");
    
        Log( "vmarg %d:%s.\n",0,vmargs[0]);
        Log( "vmarg %d:%s.\n",1,vmargs[1]);
        Log( "vmarg %d:%s.\n",2,vmargs[2]);
        Log( "vmarg %d:%s.\n",3,vmargs[3]);
        Log( "vmarg %d:%s.\n",4,vmargs[4]);
    }
    

    将 -Xdebug 与 -Xrunjdwp 分开允许 JVM 识别它们。当它们共享一个 char* 时,JVM 并没有将它们解析为两个选项,而是认为它们是一个选项。

    【讨论】:

      猜你喜欢
      • 2017-12-19
      • 2021-12-14
      • 1970-01-01
      • 2012-12-07
      • 2011-06-10
      • 1970-01-01
      • 2016-04-02
      • 2018-08-22
      • 2015-01-19
      相关资源
      最近更新 更多