问题集锦(54-55)
来源:互联网 发布:js获取input的属性值 编辑:程序博客网 时间:2024/05/16 23:59
Problem 54 An example for understanding Linux initcall mechanism?
Ans:
1. 源码
#include <stdio.h>
/*定义函数指针*/
typedef int (*initcall_t)(void);
/*申明外部变量,在ld的脚本文件中定义*/
extern initcall_t __initcall_start, __initcall_end;
#define __initcall(fn) /
static initcall_t __initcall_##fn __init_call = fn
#define __init_call __attribute__ ((unused,__section__ ("function_ptrs")))
#define module_init(x) __initcall(x);
/*上述宏定义名为"__initcall_函数名"的函数指针,且将函数指针放在function_ptrs节
这个函数指针,指向fn(fn函数则放在code_segment节中)*/
#define __init __attribute__ ((__section__ ("code_segment")))
/*函数放在code_segment节*/
static int __init
my_init1 (void)
{
printf ("my_init () #1/n");
return 0;
}
static int __init
my_init2 (void)
{
printf ("my_init () #2/n");
return 0;
}
module_init (my_init1);/*定义要被调用的函数指针并放到指定的节中*/
module_init (my_init2);
void
do_initcalls (void)
{
initcall_t *call_p; /*定义函数指针变量*/
call_p = &__initcall_start;/*获取节首址*/
do {
fprintf (stderr, "call_p: %p/n", call_p);
(*call_p)();
++call_p;/*32位机器上,函数指针占4bytes,增加一次就是指针便宜4bytes*/
} while (call_p < &__initcall_end);
}
int
main (void)
{
fprintf (stderr, "in main()/n");
do_initcalls (); /*调用*/
return 0;
}
2. 定义lds文件
通过命令ld --verbose可以获得默认的连接控制脚本, 即选择 "=======..."之间的文本,保存为linker.lds文件
在linker.lds文件中增加本例需要控制的语句:
将
/*定义__initcall_start符号为当前位置,即.代表当前位置*/
__initcall_start = .;
function_ptrs : { *(function_ptrs) }
__initcall_end = .;
/*上述3行代码代表function_ptrs节位于__initcall_start和__initcall_end之间*/
code_segment : { *(code_segment) }
这段代码copy到linker.lds文件的
__bss_start = .;
语句之前。
这项工作可由如下脚本完成:
#!/bin/sh
outputfile=linker.lds
lineno1=`ld --verbose | tee ${outputfile} | sed '/==================================================/q' | wc -l`
sed -i "1,${lineno1}d" ${outputfile}
sed -i '/==================================================/d' ${outputfile}
lineno2=`sed -n '/__bss_start/=' ${outputfile}`
sed -i "${lineno2} i/__initcall_start = .;/nfunction_ptrs : { *(function_ptrs) }/n__initcall_end = .;/ncode_segment : { *(code_segment) } " ${outputfile}
3. 编译运行
命令:
gcc -Tlinker.lds -o doinitcall doinitcall.c
其中:
-T选项告诉ld要用的连接控制脚本文件,做为链接程序的依据。格式如下:
-T commandfile 或
--script=commandfile
运行结果如下:
byd123@ubuntu:~/Desktop$ ./doinitcall
in main()
call_p: 0x804a01c
my_init () #1
call_p: 0x804a020
my_init () #2
Problem 55系统管理:Linux系统下临时文件TMP清理?
Ans:
系统使用时间长后会产生临时文件(/tmp下),需要清理,但清理的时候不推荐使用rm –rf。这样有时会引起程序的僵死。推荐使用tmpwatch工具。
tmpwatch工具从指定的目录中递归地搜索,并删除在指定时间段内没有被访问的文件。tmpwatch一般被用来清扫那些用来临时驻留文件的目录(如/tmp),tmpwatch忽略符号链接,它不会切换文件系统,而且只删除空目录和常规文件。
语法: tmpwatch [-afqv] [-test][超期时间][目录…]
补充说明:执行tmpwatch指令可删除不必要的暂存文件,您可以设置文件超期时间,单位以小时计算。
参数:
-a或--all 删除任何类型的文件
-f或--force 强制删除文件或目录,其效果类似rm指令的”-f”参数。
-q或--quiet 不显示指令执行过程
-v或--verbose 详细显示指令执行过程
-test 仅作测试,并不真的删除文件或目录
实例:tmpwatch -afv 3 /tmp
- 问题集锦(54-55)
- 问题集锦
- 问题集锦
- 问题集锦
- 问题集锦
- 问题集锦
- 问题集锦
- 问题集锦
- 问题集锦
- 问题集锦
- 问题集锦
- 问题集锦
- 问题集锦
- 问题集锦
- 问题集锦
- 问题集锦
- WMI问题答案集锦
- SQA 问题集锦
- Editplus 代码自动完成 代码片段 代码缩写
- 多重继承会带来哪些问题?
- 【代码猴子-培养正确的编程态度和方法】--《编程匠艺》
- 拒绝形式化的软件工程文档
- Struts2_0900_ModelDrivenParamInput 使用ModelDriven接收参数
- 问题集锦(54-55)
- 来自淘宝的架构设计原则
- Bloom Filter概念和原理
- 关于window.showModalDialog()返回值的学习心得
- 简单的JAVASCRIPT画图函数(兼容ie/ff)
- Js之window对象使用
- useful command
- “时间管理”学习
- 电影《遗愿清单》