简体   繁体   English

Runtime.getRuntime.exec 139 (SIGSEGV) 来自 Java 用于 C 程序

[英]Runtime.getRuntime.exec 139 (SIGSEGV) from Java for C programs

I'm creating a Java program to run C executables, using Runtime.getRuntime.exec(String command) method, but sometimes it returns exitValue=139(SIGSEGV) even if C programs work fine when I run them from terminal or Eclipse. I'm creating a Java program to run C executables, using Runtime.getRuntime.exec(String command) method, but sometimes it returns exitValue=139(SIGSEGV) even if C programs work fine when I run them from terminal or Eclipse.

What could be the problem?可能是什么问题呢?

Process pro = Runtime.getRuntime().exec("./cExecutable 10");

System.out.println(command + " exitValue=" + pro.exitValue());

If it can be useful, I'm using Ubuntu 18.04.如果它有用,我正在使用 Ubuntu 18.04。

Important, I also noticed that it happens most frequently when executable output has more than 600 lines.重要的是,我还注意到,当可执行文件 output 超过 600 行时,它最常发生。

In fact outputs of my programs are very large事实上我的程序的输出非常大

Java process launcher is can freeze if the STDERR/OUT streams of the sub-process are not read, but I've never seen this cause SIGSEGV in the sub-process so this may not help you. Java 如果子进程的 STDERR/OUT 流未被读取,进程启动器可能会冻结,但我从未见过这会导致子进程中的 SIGSEGV,所以这可能对您没有帮助。

However as you say your apps write a lot of data then it may be worth fixing your launcher to consume the output streams.但是,正如您所说,您的应用程序写入了大量数据,那么可能值得修复您的启动器以使用 output 流。 ProcessBuilder gives better control over the launch than Runtime.getRuntime , this example writes STDERR/OUT streams to files so you don't need to consume in background threads: ProcessBuilderRuntime.getRuntime更好地控制启动,此示例将 STDERR/OUT 流写入文件,因此您无需在后台线程中使用:

String[] cmd = new String[] {"cExecutable","10"};
ProcessBuilder pb = new ProcessBuilder(cmd);

// Set up STDOUT:
Path tmpdir = Path.of(System.getProperty("java.io.tmpdir"));
Path fn = Path.of(cmd[0]).getFileName();
Path out = tmpdir.resolve(fn+"-stdout.log");
pb.redirectOutput(out.toFile());

// EITHER: Set up STDERR:
Path err = tmpdir.resolve(fn+"-stderr.log");
pb.redirectError(err.toFile());
// OR: join err to std with
// pb.redirectErrorStream(true);

// Launch and wait:
Process p = pb.start();
long pid = p.pid();
System.out.println("started PID "+pid);

// could close STDIN to signal end of input
p.getOutputStream().close();

int rc = p.waitFor();

System.out.println("Exit PID "+pid+": RC "+rc +" => "+(rc == 0 ? "OK": "**** ERROR ****"));
System.out.println("STDOUT: \""+Files.readString(out)+'"');
System.out.println("STDERR: \""+Files.readString(err)+'"');

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM