`
wangleyiang
  • 浏览: 220862 次
社区版块
存档分类
最新评论

linux so

阅读更多

来源:http://mypyg.iteye.com/blog/845915

 

1.so文件是什么?
也是ELF格式文件,共享库(动态库),类似于DLL。节约资源,加快速度,代码升级简化。
知道这么多就够了,实用主义。等有了印象再研究原理。
2.怎么生成以及使用一个so动态库文件?
先写一个C文件:s.c

 #include <stdio.h>
 int count;
 void out_msg(const char *m)
 {//2秒钟输出1次信息,并计数
  for(;;) {printf("%s %d\n", m, ++count); sleep(2);}
 }

 编译:得到输出文件libs.o
gcc -fPIC -g -c s.c -o libs.o
链接:得到输出文件libs.so
gcc -g -shared -Wl,-soname,libs.so -o libs.so libs.o -lc

一个头文件:s.h

#ifndef _MY_SO_HEADER_
 #define _MY_SO_HEADER_
 void out_msg(const char *m);
 #endif

 再来一个C文件来引用这个库中的函数:ts.c

#include <stdio.h>
 #include "s.h"
 int main(int argc, char** argv)
 {
  printf("TS Main\n");
  out_msg("TS ");
  sleep(5);  //这句话可以注释掉,在第4节的时候打开就可以。
  printf("TS Quit\n");
 }

 编译链接这个文件:得到输出文件ts
gcc -g ts.c -o ts -L. -ls

执行./ts,嗯:成功了。。。还差点
得到了ts:error while loading shared libraries: libs.so: cannot open shared object file: No such file or directory
系统不能找到我们自己定义的libs.so,那么告诉他,修改变量LD_LIBRARY_PATH,为了方便,写个脚本:e(文件名就叫e,懒得弄长了)
#!/bin/sh
export LD_LIBRARY_PATH=${pwd}:${LD_LIBRARY_PATH}
./ts
执行:./e &
屏幕上就开始不停有信息输出了,当然TS Quit你是看不到的,前面是个死循环,后面会用到这句
3.地址空间,以及线程安全:
如果这样:
./e &开始执行后,稍微等待一下然后再 ./e&,
这个时候屏幕信息会怎么样呢?全局变量count会怎么变化?
会是两个进程交叉输出信息,并且各自的count互不干扰,虽然他们引用了同一个so文件。
也就是说只有代码是否线程安全一说,没有代码是否是进程安全这一说法。
4.库的初始化,解析:
windows下的动态库加载,卸载都会有初始化函数以及卸载函数来完成库的初始化以及资源回收,linux当然也可以实现。
ELF文件本身执行时就会执行一个_init()函数以及_fini()函数来完成这个,我们只要把自己的函数能让系统在这个时候执行
就可以了。
修改我们前面的s.c文件:

#include <stdio.h>
 void my_init(void) __attribute__((constructor)); //告诉gcc把这个函数扔到init section
 void my_fini(void) __attribute__((destructor));  //告诉gcc把这个函数扔到fini section
 void out_msg(const char *m)
 {
  printf(" Ok!\n"); 
 }
 int i; //仍然是个计数器
 void my_init(void)
 {
  printf("Init ... ... %d\n", ++i);
 }
 void my_fini(void)
 {
  printf("Fini ... ... %d\n", ++i);
 }

 重新制作 libs.so,ts本是不用重新编译了,代码维护升级方便很多。
然后执行: ./e &
可以看到屏幕输出:(不完整信息,只是顺序一样)
Init
Main
OK
Quit
Fini
可以看到我们自己定义的初始化函数以及解析函数都被执行了,而且是在最前面以及最后面。
如果s.c中的sleep(5)没有注释掉,那么有机会:
./e&
./e&连续执行两次,那么初始化函数和解析函数也会执行两次,虽然系统只加载了一次libs.so。
如果sleep时候kill 掉后台进程,那么解析函数不会被执行。
5.使用我们自己库里的函数替换系统函数:
创建一个新的文件b.c:我们要替换系统函数malloc以及free(可以自己写个内存泄露检测工具了)

#include <stdio.h>
 void* malloc(int size)
 {
  printf("My malloc\n");
  return NULL;
 }
 void free(void* ad)
 {
  printf("My free\n");
 }

 老规矩,编译链接成一个so文件:得到libb.so
gcc -fPIC -g -c b.c -o libb.o
gcc -g -shared -Wl,-soname,libb.so -o libb.so -lc
修改s.c:重新生成libs.so

void out_msg()
 {
  int *p;
  p = (int*)malloc(100);
  free(p);
  printf("Stop Ok!\n");
 }

 修改脚本文件e:
#!/bin/sh
export LD_PRELOAD=${pwd}libb.so:${LD_PRELOAD}
export LD_LIBRARY_PATH=${pwd}:${LD_LIBRARY_PATH}
./ts
关键就在LD_PRELOAD上了,这个路径指定的so将在所有的so之前加载,并且符号会覆盖后面加载的so文件中的符号。如果可执行文件的权限不合适(SID),这个变量会被忽略。
执行:./e &
嗯,可以看到我们的malloc,free工作了。

 

 

分享到:
评论

相关推荐

    vs2015跨平台linux开发so库例子

    标题中的“vs2015跨平台Linux开发so库例子”指的是使用Visual Studio 2015进行跨平台开发,创建适用于Linux系统的动态链接库(.so文件)。Visual Studio 2015引入了对Linux开发的支持,允许开发者在Windows环境下...

    LINUX动态库.so嵌套.so文件

    在Linux系统中,动态库(.so文件)是程序运行时加载的共享对象,它们提供了函数和数据供其他程序调用。"LINUX动态库.so嵌套.so文件"的主题涉及了如何在一个动态库中嵌入另一个动态库,这种技术通常用于代码重用和...

    libsigar 鲲鹏,麒麟版本 linux so动态库

    libsigar 鲲鹏,麒麟版本 linux so动态库。 arm版本so库

    delphi编写so库,及调用实例,linux下运行,Deepin系统

    本篇将深入探讨如何使用Delphi编写共享库(SO库)并在Linux的Deepin操作系统上运行和调用。 首先,我们要理解`so库`是什么。在Unix-like系统(包括Linux)中,`.so`文件是Shared Object Library的缩写,相当于...

    opencv 470版本java语言依赖库 linux环境so文件

    opencv 470版本java语言依赖库 linux环境so文件

    linux 下 libssl.so.10 libcrypto.so.10

    在Linux操作系统中,`libssl.so.10`和`libcrypto.so.10`是两个非常关键的共享库文件,它们属于OpenSSL库的一部分。OpenSSL是一个强大的安全套接层(SSL)和传输层安全(TLS)协议实现,同时也包含了一些常用的加密...

    linux x86平台elf 进程注入so并且实现基于rel的hook ubuntu14.01测试通过

    本主题探讨的是在x86架构的Linux平台上,如何将动态链接库(.so文件)注入到运行中的ELF进程,并实现基于相对地址(Relocation-based,简称rel)的钩子(hook)技术。Ubuntu 14.01是这个实践的测试环境。 首先,...

    linux_so.rar_linux so

    linux动态链接库的创建和使用,供大家好好研究。

    libsigar-amd64-linux.so和libsigar-x86-linux.so

    本文将深入探讨libsigar库及其在Linux环境下的两个关键组件:libsigar-amd64-linux.so和libsigar-x86-linux.so。 libsigar是一个跨平台的库,由Hewlett Packard Enterprise开发并维护,其主要目标是简化对操作系统...

    linux下编译.so库文件

    在Linux环境下编译.so库文件是一项关键技能,尤其对于软件开发者而言。本文将深入解析Linux下编译.so库文件的过程,以及与之相关的静态库和动态库的基本概念,旨在为读者提供一个全面的理解。 ### 一、理解库文件...

    JNI(java-c).rar_C/C++层回调Java_JAVA LINUX so_NDK SO_java jni linux

    1.hello-jin-c是linux下的c实现文件。 (使用NDK编译成.so文件,供java层调用)。 2.helloJni是java工程。(里面通过JNI调用下面.so中提供的c的实现。) 同理.so里面也可以调用回调java里面实现的文件。

    java操作串口的jar包与dll/so文件,RXTX的64位linux/windows两个版本

    在Windows上,RXTX库通常需要一个动态链接库(DLL)文件,而在Linux上则需要共享对象(SO)文件。这两个文件类型都包含了运行时所需的本机代码,以支持Java程序的串口操作。解压提供的ZIP文件后,用户将找到这些特定...

    libsigar-amd64-linux.so libsigar-x86-linux.so

    标题中的“libsigar-amd64-linux.so”和“libsigar-x86-linux.so”是两个重要的库文件,它们属于Sigar(System Information Gatherer and Reporter)库,一个跨平台的系统性能监控工具。在Java应用程序中,这些动态...

    libsigar-amd64-linux.so以及libsigar-x86-linux.so

    标题中的"libsigar-amd64-linux.so"和"libsigar-x86-linux.so"是两个重要的库文件,它们属于Sigar(System Information Gatherer and Reporter)项目,一个跨平台的系统性能监控工具集。Sigar由Hewlett Packard ...

    opencv库(windows+linux版本)

    `libopencv_java480.so`是针对Java的Linux版本,它与Windows上的DLL类似,但格式适应于Linux的动态链接机制。这里的版本号480表明这是OpenCV的一个较早版本,可能与最新的490有所不同。在Linux环境中,开发者需要...

    安装linux的so库

    ### 安装Linux的SO库及解决libz.so.1缺失问题 在Linux环境中,动态链接库(Dynamic Link Library,简称DLL,在Linux中通常被称为共享对象文件或.so文件)是程序运行时依赖的重要组成部分。当遇到类似“找不到libz....

    同时支持linux和Windows下java与串口通信的rxtx包,亲测可用

    cp librxtxSerial.so $JAVA_HOME/jre/lib/amd64/ cp RXTXcomm.jar $JAVA_HOME/jre/lib/ext windows下安装路径为: Copy RXTXcomm.jar ---&gt; &lt;JAVA_HOME&gt;\jre\lib\ext Copy rxtxSerial.dll ---&gt; &lt;JAVA_HOME&gt;\jre...

    反编译神器jeb(linux版)

    《反编译神器JEB(Linux版):深入解析与应用》 在IT行业中,软件安全分析和逆向工程是至关重要的领域,其中反编译工具扮演着举足轻重的角色。今天我们要聚焦的是名为“JEB”的反编译神器,特别是其Linux版本。JEB...

    linux下生成so文件并且调用so文件的方法

    在Linux环境下,生成和调用共享库(SO文件,即Shared Object)是常见的软件开发实践。SO文件允许多个程序共享同一段代码,节省内存并提高系统效率。下面将详细介绍如何生成SO文件以及如何在应用程序中调用它们。 一...

    sigar-linux依赖 libsigar-amd64-linux.so

    "sigar-linux依赖 libsigar-amd64-linux.so" 这个标题表明 Sigar 在Linux系统上运行时需要依赖名为 `libsigar-amd64-linux.so` 的动态链接库文件。这个库是专门为64位(AMD64架构)的Linux系统编译的。 **libsigar-...

Global site tag (gtag.js) - Google Analytics