【问题标题】:MSVCRT system function return code is always -1MSVCRT 系统函数返回码始终为 -1
【发布时间】: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 上不起作用。

标签: c windows-7 msvcrt


【解决方案1】:

我给自己添加了一个答案,因为我认为这已经完成了。

ComSpecC:\Windows\System32\cmd.exe 更改为 C:\Windows\winsxs\amd64_microsoft-windows-commandprompt_31bf3856ad364e35_6.1.7601.17514_none_e932cc2c30fc13b0\cmd.exe 解决了我遇到的所有假退出代码问题。

【讨论】:

    【解决方案2】:

    这是 'system()' 手册中关于返回值的说明

       The value returned is -1 on  error  (e.g.,  fork(2)  failed),  and  the
       return  status  of the command otherwise.  This latter return status is
       in the format specified in wait(2).  Thus, the exit code of the command
       will  be  WEXITSTATUS(status).   In case /bin/sh could not be executed,
       the exit status will be that of a command that does exit(127).
    
       If the value of command is NULL, system() returns nonzero if the  shell
       is available, and zero if not.
    
       system() does not affect the wait status of any other children.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-01
      • 1970-01-01
      • 2017-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多