Linux respawn格式说明 linux rear
文章目录
- 1. Linux的errno和指针
- 1.1. 整型和指针类型转换
- 2.1. 负数的强制类型转换
- 2.2. 强制数据类型降级
- 3. 测试程序
- 3.1. ARM测试结果
- 3.2. ARM64测试结果
1. Linux的errno和指针
常见的Linux函数返回值类型包括整型和指针,内核中这两种返回值类型的函数会互相调用。Linux的errno为整型,为了与errno对应,Linux将指针分为3种:
- 空指针:NULL,地址为0
- 异常指针:地址空间的高4095字节。0xfffff001 - 0xffffffff(32位)和0xfffffffffffff001 - 0xffffffffffffffff(64位)
- 普通指针
errno的最大值MAX_ERRNO在err.h定义,值为4095。关于变量转换类型后的值,可以使用测试程序来进行测试。
long
void *(arm)
unsigned long(arm)
void *(arm64)
unsigned long(arm64)
0
(nil)
0
(nil)
0
-1
0xffffffff
0xFFFFFFFF
0xffffffffffffffff
0xFFFFFFFFFFFFFFFF
-MAX_ERRNO
0xfffff001
0xFFFFF001
0xfffffffffffff001
0xFFFFFFFFFFFFF001
为了处理两种数据类型的转换,内核提供了include/linux/err.h。
1.1. 整型和指针类型转换
interface
input
output
function
IS_ERR_VALUE
any
bool
强制转换为unsigned long后,判断是否大于(unsigned long)-MAX_ERRNO
ERR_PTR
long
void *
errno转指针
PTR_ERR
pointer
long
指针转errno
IS_ERR
pointer
bool
判断指针是否异常
IS_ERR_OR_NULL
pointer
bool
判断指针是否异常或NULL
ERR_CAST
pointer
void *
将任意类型的指针转为void型指针
PTR_ERR_OR_ZERO
pointer
int
如果是异常指针,返回指针对应的errno,否则返回0
2. C语言中整型数据的存储和数据类型转换原理
其实,在C语言中,数值是以补码的形式存储的,正数存储的内容就是其本身(原码),负数补码的计算方法如下:
以char型为例,-1在内存中的表示计算方法如下:
关于为什么使用补码存储数据,可以参整数在内存中是如何存储的,为什么它堪称天才般的设计。
2.1. 负数的强制类型转换
做强制类型转换时,就是把内存中的数据(补码)看作要转换的类型。将-1强制转换为unsigned char型时,就可得到值为0xFF,以此类推,可知将-转换为unsigned long时,值为0xFFFFFFFF(32位)或0xFFFFFFFFFFFFFFFF(64位)。同样的道理-4095转换为unsigned long时,值为0xFFFFF001(32位)或0xFFFFFFFFFFFFF001(64位)。需要注意的是,类型转换是临时的,转换的结果也会保存到临时的内存空间,不会改变数据本来的类型或者值。
2.2. 强制数据类型降级
数据类型级别从高到低为:
unsigned long long long long unsigned long long unsigned int int unsigned short short unsigned char char从高级到低级转换时,超出数值位数的高位部分将被丢弃。另外,降级转换也是是临时的。
3. 测试程序
#include <stdio.h> #include <string.h> #define MAX_ERRNO 4095 union err_t { int i; long l; unsigned int ui; unsigned long ul; void *p; char ch[sizeof(unsigned long)]; }; static void test(long val) { union err_t err; memcpy(&err, &val, sizeof(val)); printf("int: %d\n", err.i); printf("long: %ld\n", err.l); printf("unsigned int: %u, 0x%08X\n", err.ui, err.ui); printf("unsigned long: %lu, 0x%08lX\n", err.ul, err.ul); printf("void *: %p\n", err.p); } int main(void) { printf("\ntesting: 0\n"); test(0); printf("\ntesting: -1\n"); test(-1); printf("\ntesting: -MAX_ERRNO\n"); test(-MAX_ERRNO); #if 0 printf("\ntesting: -4096\n"); test(-4096); #endif return 0; }3.1. ARM测试结果
交叉编译后使用QEMU运行查看结果。
arm-linux-gnueabihf-gcc -static -o err_arm err.c qemu-arm err_armtesting: 0 int: 0 long: 0 unsigned int: 0, 0x00000000 unsigned long: 0, 0x00000000 void *: (nil) testing: -1 int: -1 long: -1 unsigned int: 4294967295, 0xFFFFFFFF unsigned long: 4294967295, 0xFFFFFFFF void *: 0xffffffff testing: -MAX_ERRNO int: -4095 long: -4095 unsigned int: 4294963201, 0xFFFFF001 unsigned long: 4294963201, 0xFFFFF001 void *: 0xfffff0013.2. ARM64测试结果
交叉编译后使用QEMU运行查看结果。
aarch64-linux-gnu-gcc -static -o err_aarch64 err.c qemu-aarch64 err_aarch64testing: 0 int: 0 long: 0 unsigned int: 0, 0x00000000 unsigned long: 0, 0x00000000 void *: (nil) testing: -1 int: -1 long: -1 unsigned int: 4294967295, 0xFFFFFFFF unsigned long: 18446744073709551615, 0xFFFFFFFFFFFFFFFF void *: 0xffffffffffffffff testing: -MAX_ERRNO int: -4095 long: -4095 unsigned int: 4294963201, 0xFFFFF001 unsigned long: 18446744073709547521, 0xFFFFFFFFFFFFF001 void *: 0xfffffffffffff001
解决Python格式化提供者找不到的错误:实用技巧与工具推荐
How to Download Windows 10 Spotlight/Lock Screen ImagesDownload Windows 10
linux respawn命令 linux rescue模式
linux下reboot和shutdown关机命令详解linux关机命令shutdown立刻关机
Linux namespaces linux namespace实现
linux namespaces 详解 linux namespace技术
Python Download URL: Automate File Downloads Effortlessly with Step-by-Step Guide