【发布时间】:2015-06-27 22:35:44
【问题描述】:
什么会导致 MSVCRT system() 函数总是返回 -1 错误代码,即使应用程序已成功执行并退出 并返回 0 作为其退出代码?
我用 TDM-GCC-4.9.2 和 FASM 进行了测试,只调用 system() 并打印返回码,它们都打印 -1 所以它不是我的开发环境。
在调用system() 和GetLastError 返回18 没有更多文件之后,errno 也是0,这很奇怪。
事实上,每个系统上使用 system() 的应用程序现在总是假定它失败了。
所以这是 MSVCRT 的一个全球性问题,我似乎无法在任何其他机器上重现,我们将不胜感激。
编辑:经过一些调试,system 调用 _spawnve,后者又调用 CreateProcessA,然后是 WaitForSingleObject。可执行文件终止后,它调用GetExitCodeProcess,即返回-1,然后反馈到链上。
EDIT 2:经过更多测试,system 似乎仅在被调用进程返回 0 时返回 -1 否则返回正确的值。
EDIT 3:澄清一下,即使system返回-1,被调用的进程也成功执行了。
编辑 4:这是我的测试来源。
总是返回 0 成功的那个:
#include <stdio.h>
int main( int argc, char* argv[argc]) {
printf("success\n");
return 0;
}
总是失败的那个:
#include <stdio.h>
int main( int argc, char* argv[argc]) {
printf("failure\n");
return 1;
}
还有那个叫它的人:
#include <stdlib.h>
#include <stdio.h>
int main( int argc, char* argv[argc]) {
printf( "success == %d %d\n", system("test_success.exe", errno);
printf( "failure == %d %d\n", system("test_fail.exe", errno);
return 0;
}
这个的输出是:
success
success == -1 0
failure
failure == 1 0
EDIT 5:由于system 调用_spawnve 调用CreateProcess 我都尝试了它们,当调用cmd /c test_success 时它们都返回-1 但是当致电cmd /c test_fail 他们按预期工作。
所以这似乎是一个与system没有直接关系的更深层次的问题。
编辑 6:经过一番折腾,我将 ComSpec 更改为 C:\Windows\winsxs\amd64_microsoft-windows-commandprompt_31bf3856ad364e35_6.1.7601.17514_none_e932cc2c30fc13b0\cmd.exe,现在一切正常!
这有点奇怪,因为我在 Intel Core 2 Duo 上,这可能不是正确的做法,但我仍然满意:p
【问题讨论】:
-
您是否尝试过使用调试器进入 system() 函数以查看发生了什么?此外,检查 ComSpec 环境变量的值,并确保
cmd.exe本身没有以某种方式损坏。 -
@HarryJohnston:COMSPEC 是 "C:\Windows\System32\cmd.exe" 并使用 /c 递归调用它按预期工作。不过我会尝试调试它...
-
您是否尝试使用
GetLastError()并检查错误代码? -
@GingerJack:GetLastError 返回 18“没有更多文件”,这没有任何意义。
-
请显示您的确切代码。如果是
system("ls"),那么你的测试是错误的,因为 ls 在 Windows/cmd.exe 上不起作用。