点滴1@glibc

void (*signal (int sig, void (*handler)(int)))(int)  复杂 -> 拆开看

glibc/signal/signal.h

/* Type of a signal handler.  */
typedef void (*__sighandler_t) (int);

glibc/signal/signal.c

/* Set the handler for the signal SIG to HANDLER,
   returning the old handler, or SIG_ERR on error.  */
__sighandler_t
signal (sig, handler)
     int sig;
     __sighandler_t handler;
{
  __set_errno (ENOSYS);
  return SIG_ERR;
}

weak_alias (signal, ssignal)

别名机制

glibc/include/libc-symbols.h

/* Define ALIASNAME as a weak alias for NAME.
   If weak aliases are not available, this defines a strong alias.  */
# define weak_alias(name, aliasname) _weak_alias (name, aliasname)
# define _weak_alias(name, aliasname) \
  extern __typeof (name) aliasname __attribute__ ((weak, alias (#name)));

Declaring Attributes of Functions

In GNU C, you declare certain things about functions called in your program which help the compiler optimize function calls and check your code more carefully.

The keyword __attribute__ allows you to specify special attributes when making a declaration. This keyword is followed by an attribute specification inside double parentheses. The following attributes are currently defined for functions on all targets: alignedalloc_sizenoreturn,returns_twicenoinlinealways_inlineflattenpureconstnothrowsentinelformatformat_argno_instrument_functionsectionconstructordestructorusedunuseddeprecatedweakmallocaliaswarn_unused_resultnonnullgnu_inlineexternally_visiblehotcoldartificialerror and warning. Several other attributes are defined for functions on particular target systems. Other attributes, including section are supported for variables declarations (see Variable Attributes) and for types (see Type Attributes)

You may also specify attributes with `__' preceding and following each keyword. This allows you to use them in header files without being concerned about a possible macro of the same name. For example, you may use __noreturn__ instead of noreturn.

See Attribute Syntax, for details of the exact syntax for using attributes.

alias (" target ")
The  alias attribute causes the declaration to be emitted as an alias for another symbol, which must be specified. For instance,
          void __f () { /* Do something. */; }
          void f () __attribute__ ((weak, alias ("__f")));     

defines `f' to be a weak alias for `__f'. In C++, the mangled name for the target must be used. It is an error if `__f' is not defined in the same translation unit.

Not all target machines support this attribute. 

Assembler (GAS) 别名机制

#  ifdef HAVE_ASM_GLOBAL_DOT_NAME
#   define strong_alias(original, alias)				\
  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME (alias) ASM_LINE_SEP		\
  .set C_SYMBOL_NAME (alias),C_SYMBOL_NAME (original) ASM_LINE_SEP	\
  ASM_GLOBAL_DIRECTIVE C_SYMBOL_DOT_NAME (alias) ASM_LINE_SEP		\
  .set C_SYMBOL_DOT_NAME (alias),C_SYMBOL_DOT_NAME (original)
#   define strong_data_alias(original, alias)				\
  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME (alias) ASM_LINE_SEP		\
  .set C_SYMBOL_NAME (alias),C_SYMBOL_NAME (original)
#  else
#   define strong_alias(original, alias)				\
  ASM_GLOBAL_DIRECTIVE C_SYMBOL_NAME (alias) ASM_LINE_SEP		\
  .set C_SYMBOL_NAME (alias),C_SYMBOL_NAME (original)
#   define strong_data_alias(original, alias) strong_alias(original, alias)
#  endif

.set 参考下文,https://www.ece.cmu.edu/~ee349/f-2012/lab2/gas-tips.pdf

2.1 Determining the Length of Strings in AssemblyThe “.” symbol refers to the current assembling address, and the “.set” directive assigns a value to asymbol. Combined, one may determine the size of a section of assembly code by subtracting the currentaddress from a label and assigning the result to a symbol. For example, the following code sets the symbolhello size to the size of the string hello str:

hello_str:

.ascii "Hello world!\n"

.set hello_size, .-hello_str

With this code, modifications to the hello str string will automatically change the value of hello sizeaccordingly.

typeof or __typeof

If you are writing a header file that must work when included in ISO C programs, write __typeof__ instead of typeof. See Alternate Keywords.

typeof-construct can be used anywhere a typedef name could be used. For example, you can use it in a declaration, in a cast, or inside of sizeof or typeof.

     #define max(a,b) \
       ({ typeof (a) _a = (a); \
           typeof (b) _b = (b); \
         _a > _b ? _a : _b; })
This declares  y  as an array of pointers to characters:
          typeof (typeof (char *)[4]) y;     

It is equivalent to the following traditional C declaration:

          char *y[4];     

To see the meaning of the declaration using typeof, and why it might be a useful way to write, rewrite it with these macros:

          #define pointer(T)  typeof(T *)
          #define array(T, N) typeof(T [N])     

Now the declaration can be rewritten this way:

          array (pointer (char), 4) y;
<think>我们正在讨论Kubernetes中Pod退出码与OOM(内存不足)的关系。用户想知道OOM导致的退出是否有固定的退出码。根据我们对LinuxKubernetes的了解,当容器因为内存不足(OOM)被杀死时,通常会有一个特定的退出码。在Linux系统中,当一个进程因为内存不足被OOMkiller杀死时,该进程会收到一个特定的信号(SIGKILL,信号编号9),并且其退出码通常会被设置为137(因为128+9=137)。但是,需要注意的是,OOMkiller杀死进程时,进程本身不会有机会执行退出处理,而是由内核直接终止。因此,这个退出码是由容器运行时(如Docker)设置的,表示进程被外部信号终止。另外,还有一种情况是容器因为内存使用超过限制而退出,但可能不是由OOMkiller触发的,而是由容器运行时主动终止的。这种情况下,退出码可能也是137。然而,还有一种退出码是134,它对应的是128+SIGABRT(6)=134。当应用程序因为内存分配失败而主动中止时(例如,glibc的malloc在内存不足时调用abort),可能会产生这个退出码。但是,更常见的情况是,当容器因为内存不足被杀死时,退出码是137(SIGKILL)或143(SIGTERM,如果先尝试优雅终止的话)。不过,在Kubernetes中,如果容器因为内存资源限制被终止,通常是由kubelet发送SIGTERM信号,等待一段时间(默认为30秒)后,如果容器没有终止,则发送SIGKILL信号。但是,如果内存使用超过限制,kubelet可能会直接杀死容器(发送SIGKILL)而不等待优雅终止,因为内存不足是紧急情况。因此,我们可以总结:1.当容器因为内存不足(OOM)被强制杀死时,退出码通常是137(表示被SIGKILL信号终止)。2.有时,我们也会看到退出码为134,这可能是应用程序自己因为内存分配失败而中止(SIGABRT)。但是,根据Kubernetes官方文档Linux信号处理惯例,137是最常见的OOM退出码。另外,我们还可以通过查看容器的终止状态来确认原因。在Pod的状态中,如果容器因为OOM被终止,通常会在`lastState`中显示`reason:OOMKilled`。示例Pod状态片段:```lastState:terminated:containerID:docker://abcd1234...exitCode:137reason:OOMKilled...```所以,OOM导致的退出,退出码通常是固定的137(表示被SIGKILL杀死),并且在Pod的状态中会有`OOMKilled`的原因。但是注意,如果容器因为其他资源(如CPU)被限制而退出,则退出码可能不同。另外,如果容器在退出前自己返回了非0退出码(比如应用程序自己检测到内存不足而退出),那么退出码可能是应用程序自己定义的。因此,要判断是否是OOM,除了看退出码,更重要的是看Pod状态中的`reason`字段。参考引用[1]中提到了Pod的`restartPolicy`,但并没有直接提到OOM退出码。不过,我们可以根据容器退出状态码来重启(如OnFailure策略会重启非0退出码的容器)。因此,OOM退出(137)会被视为失败,从而触发重启(如果重启策略允许的话)。另外,引用[3]提到Pod处于Error状态的原因,其中可能包括资源超过限制,这可以关联到OOM。因此,回答用户的问题:OOM导致的退出通常有固定的退出码137,但这不是绝对的(比如应用程序自己abort时可能是134),但最常见的是137,并且可以通过Pod状态中的`reason:OOMKilled`来确认。现在,根据要求,我们需要生成相关问题。</think>### Kubernetes Pod OOM退出码分析 在Kubernetes中,当Pod因内存不足(OOM)被终止时,其退出码遵循固定的标准: 1. **OOM退出码固定值** 当容器因内存不足被强制终止时,会返回**137退出码**(十六进制0x8F)。该值由Linux标准定义:`128 + 9`,其中9代表`SIGKILL`信号。这是OOM事件的标准退出码[^1]。 2. **OOM终止的识别特征** - 在Pod状态中会显示`reason: OOMKilled` - 容器状态中`exitCode: 137` - 事件日志包含`Memory cgroup out of memory`错误 3. **与其他退出码的区别** | 退出码 | 含义 | 常见原因 | |--------|--------------------|-------------------| | **137** | 强制终止 | OOM Killer触发 | | 143 | 优雅终止 | SIGTERM信号 | | 126 | 权限错误 | 文件不可执行 | | 127 | 命令未找到 | 路径错误 | 4. **OOM处理流程** 当容器内存超过限制时: ```mermaid graph LR A[内存超限] --> B{是否配置cgroup} B -->|是| C[触发OOM Killer] C --> D[发送SIGKILL] D --> E[容器终止] E --> F[返回退出码137] ``` 5. **验证方法** 查看Pod状态细节: ```bash kubectl describe pod <pod-name> | grep -A 10 'Last State' ``` 典型输出: ``` Last State: Terminated Reason: OOMKilled Exit Code: 137 ``` 6. **重启策略影响** 根据引用[1],Pod的`restartPolicy`会影响OOM后的行为: - `Always`: 自动重启(默认) - `OnFailure`: 自动重启(因137≠0) - `Never`: 不再重启[^1] ### 关键结论 OOM导致的容器退出**有固定退出码137**,这是Linux内核的标准化行为。可通过Pod状态中的`OOMKilled`标识137退出码明确识别内存不足事件[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值