云so 3.2.0系统的ios11辅助功能快捷键在哪?

Linux共享库(so)动态加载和升级
&&转载请注明来源:,谢谢!^_^
&&本文链接地址:
学习Linux共享库动态加载缘于一个生产环境升级apache so文件常见错误操作:apache在运行中直接cp覆盖目标so文件,一段时间后错误日志里面出现关键词:Segmentation fault (段错误) ,一个个worker进程就这样渐渐退出,最后无法处理HTTP请求。
首先了解一下共享库的创建,源文件test.c
#include&stdio.h&
#include&unistd.h&
void test1(void){
(&This is do test1n&);
sleep(10);
(&End of test1n&);
void test2(void){
(&This is do test2n&);
sleep(10);
(&End of test2n&);
执行gcc -fPIC -shared -o libtest.so test.c 会生成共享库文件 libtest.so
参数含义:
-fPIC/-fpic: Compiler directive to output position independent code, a characteristic required by shared libraries. 创建共享库必须的参数
-shared: Produce a shared object which can then be linked with other objects to form an executable.
然后使用共享库:源文件main2.c
#include &stdio.h&
int main()
test1();
test2();
动态库链接:gcc -o main2 -L . -ltest main2.c 生成二进制程序main2
参数含义:
-L 指定动态库目录为当前目录
-l 指定动态库名test,不要写libtest.so
执行main2程序发现报错:error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory
原因是共享库不在系统默认的路径里面,可以在shell执行export LD_LIBRARY_PATH=./ 添加当前路径或者在 /etc/ld.so.conf 增加路径并ldconfig生效。
执行main2成功输出:
This is do test1
End of test1
This is do test2
End of test2
接下来是主角:动态加载,源文件main.c
#include &stdio.h&
#include &dlfcn.h& /* 必须加这个头文件 */
int main()
void *lib_handle;
void (*fn1)(void);
void (*fn2)(void);
char *error;
lib_handle = dlopen(&libtest.so&, RTLD_LAZY);
if (!lib_handle)
fprintf(stderr, &%sn&, dlerror());
fn1 = dlsym(lib_handle, &test1&);
if ((error = dlerror()) != NULL)
fprintf(stderr, &%sn&, error);
fn1();
fn2 = dlsym(lib_handle, &test2&);
if ((error = dlerror()) != NULL)
fprintf(stderr, &%sn&, error);
fn2();
dlclose(lib_handle);
接口函数介绍:
(1) dlopen
函数原型:void *dlopen(const char *libname,int flag);
功能描述:dlopen必须在dlerror,dlsym和dlclose之前调用,表示要将库装载到内存,准备使用。
如果要装载的库依赖于其它库,必须首先装载依赖库。如果dlopen操作失败,返回NULL值;如果库已经被装载过,则dlopen会返回同样的句柄。
参数中的libname一般是库的全路径,这样dlopen会直接装载该文件;如果只是指定了库名称,在dlopen会按照下面的机制去搜寻:
a.根据环境变量LD_LIBRARY_PATH查找
b.根据/etc/ld.so.cache查找
c.查找依次在/lib和/usr/lib目录查找。
flag参数表示处理未定义函数的方式,可以使用RTLD_LAZY或RTLD_NOW。RTLD_LAZY表示暂时不去处理未定义函数,先把库装载到内 存,等用到没定义的函数再说;RTLD_NOW表示马上检查是否存在未定义的函数,若存在,则dlopen以失败告终。
(2) dlerror
函数原型:char *dlerror(void);
功能描述:dlerror可以获得最近一次dlopen,dlsym或dlclose操作的错误信息,返回NULL表示无错误。dlerror在返回错误信息的同时,也会清除错误信息。
函数原型:void *dlsym(void *handle,const char *symbol);
功能描述:在dlopen之后,库被装载到内存。dlsym可以获得指定函数(symbol)在内存中的位置(指针)。
如果找不到指定函数,则dlsym会返回NULL值。但判断函数是否存在最好的方法是使用dlerror函数,
(4) dlclose
函数原型:int dlclose(void *);
功能描述:将已经装载的库句柄减一,如果句柄减至零,则该库会被卸载。如果存在析构函数,则在dlclose之后,析构函数会被调用。
编译gcc -o main main.c -ldl 生成二进制程序main,执行输出
This is do test1
End of test1
This is do test2
End of test2
到这里共享库动态加载就介绍完了:)
最后模拟一下升级so故障:
在执行main的时候,趁sleep期间cp 另外的so文件覆盖libtest.so,一会就出现Segmentation fault。
但是如果是mv 另外的so文件覆盖libtest.so,则无此问题,或者先rm libtest.so 再cp/mv 也不会有问题,因此升级方法就是这两种,当然最好是先停应用再升级。至于原因,可以参考我前一篇博客。
12.5更新:
今天咨询了维扬同学,可以用strace观察程序运行期间的系统调用,发现有不少mmap操作:
open(&/root/so/libtest.so&, O_RDONLY)
read&#40;3, &177ELF1113331&..., <span style="color: #&#41; = <span style="color: #
brk&#40;0&#41;
= 0x8227000
brk&#40;0x8248000&#41;
= 0x8248000
fstat64&#40;3, &#123;st_dev=makedev&#40;<span style="color: #, 0&#41;, st_ino=<span style="color: #, st_mode=S_IFREG|0755, st_nlink=1, st_uid=0, st_gid=0, st_blksize=<span style="color: #, st_blocks=16, st_size=<span style="color: #, st_atime
=<span style="color: #/05/13-14:13:18, st_mtime=<span style="color: #/05/13-14:13:01, st_ctime=<span style="color: #/05/13-14:13:01&#125;&#41; = 0
mmap2&#40;NULL, <span style="color: #, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0&#41; = 0x6e6000
mmap2&#40;0x6e7000, <span style="color: #, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0&#41; = 0x6e7000
close&#40;3&#41;
munmap&#40;0xb7753000, <span style="color: #&#41;
fstat64&#40;1, &#123;st_dev=makedev&#40;0, 11&#41;, st_ino=3, st_mode=S_IFCHR|0620, st_nlink=1, st_uid=0, st_gid=5, st_blksize=<span style="color: #, st_blocks=0, st_rdev=makedev&#40;<span style="color: #, 0&#41;, st_
atime=<span style="color: #/05/13-14:56:03, st_mtime=<span style="color: #/05/13-14:56:03, st_ctime=<span style="color: #/05/13-14:53:31&#125;&#41; = 0
mmap2&#40;NULL, <span style="color: #, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0&#41; = 0xb7756000
write&#40;1, &This is do test1n&, 17&#41;
rt_sigprocmask&#40;SIG_BLOCK, &#91;CHLD&#93;, &#91;&#93;, 8&#41; = 0
rt_sigaction&#40;SIGCHLD, NULL, &#123;SIG_DFL, &#91;&#93;, 0&#125;, 8&#41; = 0
rt_sigprocmask&#40;SIG_SETMASK, &#91;&#93;, NULL, 8&#41; = 0
nanosleep&#40;&#123;10, 0&#125;, 0xbfd63fe4&#41;
write&#40;1, &End of test1n&, 13&#41;
write&#40;1, &This is do test2n&, 17&#41;
rt_sigprocmask&#40;SIG_BLOCK, &#91;CHLD&#93;, &#91;&#93;, 8&#41; = 0
rt_sigaction&#40;SIGCHLD, NULL, &#123;SIG_DFL, &#91;&#93;, 0&#125;, 8&#41; = 0
rt_sigprocmask&#40;SIG_SETMASK, &#91;&#93;, NULL, 8&#41; = 0
nanosleep&#40;&#123;10, 0&#125;, 0xbfd63fe4&#41;
--- SIGSEGV &#40;Segmentation fault&#41; @ 0 &#40;0&#41; ---
+++ killed by SIGSEGV +++
SIGSEGV信号估计和mmap只读映射之后写入(覆盖)文件有关?
详见续篇。
参考资料:
/TUTORIALS/LibraryArchives-StaticAndDynamic.html
/luoxsbupt/item/a9d346bb09bc
Tags: , , ,
This entry was posted
on 星期六, 12月 1st, 2012 at 19:58
and is filed under ,
You can follow any responses to this entry through the
You can , or
from your own site.
Leave a Reply
Subscribe:
WP Cumulus Flash tag cloud by
9 or better.}

我要回帖

更多关于 iphone 辅助功能 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信