Win32 Exit code

  对于进程或者线程而言,在结束时都有一个exit code。如果我们在windows的cmd中执行完一个程序后,那么我们可以通过cmd的%ERRORLEVEL%变量来获得程序的exit code。而在Linux的shell中,我们可以通过$?变量来获得。

 

进程的exit code其实就是主线程的exit code,因为一个进程至少含有一个线程,而第一个被创建的线程称之为主线程(main thread),其他线程称之为辅助线程(worker thread)。

 

在win32上,对于C/C++程序而言,入口通常是main,而该函数的return code就是主线程,即进程的exit code了。同理,而对于线程而言,我们的线程函数的return code就是该线程的exit code了。

 

win32上一个进程的开始入口是由windows的BaseProcessStart开始的,最后才调用我们的main函数。

// real entry of a process void BaseProcessStart(pStartAddr) { __try { ExitThread(pStartAddr()); } __except(UnhandledExceptionFilterGetExceptionInformation())) { ExitProcess(GetExceptionCode()); } }

这里我们可以看到调用了函数ExitThread,这里是一个线程结束的地方,也就是主线程,如果我们的main函数没有抛出什么未处理的异常的话,那么就会调用该函数。但是如果我们有未处理的异常,那么最终会调用ExitProcess。而通常我们会在一个程序出现异常情况下,弹出一个系统对话框要求我们终止或者调试该程序,就是在处理未处理的异常时候发生的。这里是在UnhandledExceptionFilterGetExeptionInfomation中弹出的对话框。

 

我们看到对于exit code可能有2种可能

  1. 要么是main函数正常返回时的return code
  2. 要么是Exception code(详见MSDN中EXCEPTION_RECORD)

对于线程的exit code也是一样。以下是线程真正的入口

void BaseThreadStart(pStartAddress, pParam) { __try { ExitThread(pStartAddress(pParam)); } __except(UnhandledExceptionFilter(GetExceptionInformation())) { ExitProcess(GetExceptionCode()); } }

 

对于以下程序,有一个除0错误,win32中对应的Exception code为EXCEPTION_INT_DIVIDE_BY_ZERO = 0xC000 0094

int main() { int x = 0; int y = 0; x /= y; // divide by zero }

 

在cmd下执行该程序,获得返回码为-1073741676,这个值正好是EXCEPTION_INT_DIVIDE_BY_ZERO 的有符号表示。

但是在shell下执行该程序,获得的返回码为127。

根据linux中exit 的man page,exit的原型为 

void exit(int status)

并且返回给父进程的最终的exit code的值是 status & 0377,也就是在0-255之间

但是返回值127对于shell而言有特殊的意义——command not found。在这里有部分特殊意义退出码的列表。

 

进程的Exit Code最好有特殊的意义,这样我们可以通过返回码来了解一些关于进程意外结束的原因。

你可能感兴趣的:(thread,exception,windows,linux,shell,cmd)