我正在尝试诊断(并修复)位于多个组件边界上的问题;非常感谢任何有关如何获取更多信息或彻底解决问题的见解。
我有一个应用程序,它作为 C 程序启动,可以启动 Java 程序,然后可以以递归方式启动相同的 C 程序。它已经在 Linux 和 Cygwin 上运行。Java 中的程序启动范例中发现了一些错误,并将其从更简单的 Runtime 策略更新为(1.5 中新增的)ProcessBuilder 策略。由于各种不正当的原因,它使用 -c 选项启动 bash,后跟任何内容这是需要调用的。它可以在 Linux 上运行,但是当移植到 Cygwin 时,它会失败,如下所述。不幸的是,我不小心删除了正在运行的 Cygwin 实例,因此我无法轻易辨别问题是否仅仅是配置问题还是更深层次的问题。
根据记录,我不认为 Cygwin 有任何问题,但我不确定,因为我同时愚蠢地更新了 Cygwin。 (什么was我在想?!)
当 Java 尝试启动 C 程序时,会出现该错误。总是出现完全相同的错误:
加载共享库时出错:?:无法打开共享对象
文件:没有这样的文件或目录
在 cygwin 中对这个错误的研究几乎没有产生任何结果,只有这个:
http://cygwin.com/ml/cygwin/2012-03/msg00396.html http://cygwin.com/ml/cygwin/2012-03/msg00396.html
值得注意的是,运行属于标准 Cygwin 发行版一部分的映像的测试可以正常运行和工作。相比之下,程序bs.exe是在Cygwin环境中编译和链接的。
我正在考虑的一些事情是,是否可能存在我未包含在环境中的环境变量,但它应该继承调用者的环境,并且我没有看到我曾经在 cygwin 环境中使用过任何类型的 LD_LIBRARY_PATH过去并没有注意到文献中有任何类似的参考文献。然后是 Java 策略,但与以前相比没有任何改变,当我将 cygwin 添加到文件中时,它没有帮助。
...我已经没有主意了...有人吗?
更新:以下是 Java 中 ProcessBuilder 代码的代码摘录:
public results ExecuteProgram(String program, String log)
{
results r = new results();
boolean returnString = false;
if (Empty(log)) { log = getTempFile(); }
File lf = null;
ProcessBuilder pb;
r.OK = true;
r.err = "Unable to Run program: ";
int status = 0; //Note that 0 = success!
// Before we get here, we know the first space delimited substring
// of the program string already has the full path to the program. The
// rest (if any) are arguments.
try
{
// Shell contains something like /bin/bash, depending on the system
//
pb = new ProcessBuilder(Shell, "-c", program);
// Map<String, String> env = pb.environment();
// env.remove("PATH");
// env.put("PATH", Path);
// env.remove("CLASSPATH");
// env.put("CLASSPATH", CLASSPATH);
// env.remove("LD_LIBRARY_PATH");
// env.put("LD_LIBRARY_PATH", LD_LIBRARY_PATH);
// ALSO DO:
// LD_LIBRARY_PATH
pb.directory(new File(wd));
pb.redirectErrorStream(true);
lf = new File(log);
pb.redirectOutput(Redirect.appendTo(lf));
Process p = pb.start();
assert p.getInputStream().read() == -1;
if (!returnString)
{
assert pb.redirectInput() == Redirect.PIPE;
assert pb.redirectOutput().file() == lf;
}
r.err = "OS Process started.";
r.OK = true;
try
{
r.Status = p.exitValue();
r.err = "OS Process completed.";
}
catch (IllegalThreadStateException e)
{
}
}
catch (IOException e)
{
r.err += "\nIOException while accessing IO stream: "+
e.toString();
r.OK = false;
}
if ((r.Status == 0) && (r.OK))
{
r.err = "Success";
} else {
if (r.Status != 0)
{
r.err += "Process exit status: "+r.Status;
}
System.out.print(r.err);
}
return r;
}
哦,是的,按照惯例, cygcheck -s 信息如下,被剪掉了一点。由于整个数据集很大并且可能无趣,因此可以根据要求提供更多信息。
Cygwin 配置诊断当前系统时间: 12 月 5 日星期四
04:08:40 2013 Windows 7 Professional N 版本 6.1 内部版本 7600
在 AMD64 上的 WOW64 下运行 路径:C:\Program
文件\Java\jdk1.7.0\bin
C:\opt\bin
C:\cygwin\usr\local\bin
C:\cygwin\bin
C:\Program Files (x86)\Android\android-sdk\platform-tools
C:\Program Files\PostgreSQL\9.3\bin
C:\Program Files\Java\jdk1.7.0\bin
C:\Program Files (x87)\PC 连接解决方案
C:\windows\system32
C:\Windows
C:\windows\System32\Wbem
C:\windows\System32\WindowsPowerShell\v1.0
C:\Program Files (x86)\Microsoft SQL Server\90\Tools\binn
C:\Program Files (x86)\Toshiba\Bluetooth Toshiba Stack\sys
C:\Program Files (x86)\Toshiba\Bluetooth Toshiba Stack\sys\x64
C:\Program Files\Intel\WiFi\bin
C:\Program Files\Common Files\Intel\WirelessCommon
C:\cygwin\bin
C:\Program Files\PostgreSQL\9.3\bin
C:\cygwin\lib\lapack
Cygwin DLL version info:
DLL version: 1.8.4
DLL epoch: 19
DLL old termios: 5
DLL malloc env: 28
Cygwin conv: 181
API major: 0
API minor: 262
Shared data: 5
DLL identifier: cygwin1
Mount registry: 3
Cygwin registry name: Cygwin
Program options name: Program Options
Installations name: Installations
Cygdrive default prefix:
Build date:
Shared id: cygwin1S5
<snip>