回归正题,前段时间项目开发中,实现了一个动态库,封装了一些方法。然后基于这个动态库,实现了一个应用程序。应用程序中含有全局变量A,动态库中也含有全局变量A,当我调用动态库中函数后,发现应用程序的A发生了变化!!!O,My God!对于我这种还没在Linux下做过开发的人来说,一头雾水。。。。。。 于是我尝试着,将A中的变量名称改为B,这样问题也就没有了~~~
Linux下得库有动态与静态两种,动态通常用.so为后缀,静态用.a为后缀。面对比一下两者:
最近在写一个Makefile,调试时遇到了libsrcpbl.so: undefined reference to gcProgramName的问题。在这个Makefile脚本里面,终极目标是通过链接一个自定义的动态库libsrcpbl.so生成一个ELF目标文件。
opentelemetry-cpp 在标准上报协议OTLP里是支持使用 gRPC 作为传输协议的。但是,当 gRPC 被作为静态库同时链接进多个动态库时,在一些平台上会有一些问题。这是 gRPC 本身的一些实现方式导致的。 一直拖到今天才来比较完整得写这个问题的具体成因和解决方案,实际上也有一些其他库有相似实现的也会有相同的问题,所以分享出来看看有没有其他同学也可能碰到可以参考一下。
在上一篇文章中,我们一起学习了Linux系统中 GCC编译器在编译可执行程序时,静态链接过程中是如何进行符号重定位的。
最近看了一篇getopt使用的文章,为了追踪其执行的逻辑,于是采用GDB挂载调试的方式进行查看。但却出现了GDB打印全局变量optind的时候出现错误。
最近在设计一个动态库时,在全局变量中创建了线程,在Windows下动态库加载时导致死锁。根本的原因是Windows要求不可以在动态库的DllMain函数中创建线程,而我的代码结构恰好满足这个条件。 以下是简化后的示例代码:
汇编过程调用对汇编代码进行处理,生成处理器能识别的指令,保存在后缀为.o 的目标文件中。
拿到一个编译好的可执行文件,你能获取到哪些信息?文件大小,修改时间?文件类型?除此之外呢?实际上它包含了很多信息,这些你都知道吗?
堆、栈、自由存储区、全局/静态存储区、常量存储区 自由存储区存储malloc申请的内存 (1)从静态存储区域分配 。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如 全局变量, static 变量 。 (2)在栈上创建 。在执行函数时, 函数内局部变量的存储单元都可以在栈上创建 ,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集。 (3)从堆上分配 , 亦称动态内存分配 。程序在运行的时候用 malloc 或 new 申请任意多少的内存,程序员自己负责在何时用 free 或 delete 释放内存。动态内存的生存期由程序员决定,使用非常灵活,但问题也最多。
大家肯定都知道计算机程序设计语言通常分为机器语言、汇编语言和高级语言三类。高级语言需要通过翻译成机器语言才能执行,而翻译的方式分为两种,一种是编译型,另一种是解释型,因此我们基本上将高级语言分为两大类,一种是编译型语言,例如C,C++,Java,另一种是解释型语言,例如Python、Ruby、MATLAB 、JavaScript。
版权声明:本文为作者原创,如需转载请通知本人,并标明出处和作者。擅自转载的,保留追究其侵权的权利。golang群:570992072。qq 29185807 个人公众号:月牙寂道长 公众号微信号yueyajidaozhang https://blog.csdn.net/screscent/article/details/79959894
链接是将各种代码和数据片段收集并组合为一个单一文件的过程,这个文件可以被加载到内存中执行。
其实学完C语言的语法后,我们往往会有数不清的疑惑,例如编译器在编译的时候就可以分配内存,那么不同的程序会不会分配到相同的内存地址,计算机如何处理这种冲突?C语言既然可以操作内存,我们能不能修改其他程序的内存数据,游戏外挂是不是这样实现的?程序是怎么被加载到内存的,C语言main函数又是谁调用的?为什么编译之后还要链接?什么是动态库什么又是静态库?
1. 首先我们来看一个现象,当只有第一行代码时,编译是能通过的,但会报warning,当加了第二行代码时,编译无法通过,报error。 第一行代码能编过的原因是权限缩小,虽然ptr是可读可写的权限,但在指向常量字符串"hello world"之后,ptr的权限就变为了只读,所以如果仅仅修改一下权限,g++并不会报错,只是报个warning罢了,但当解引用ptr,将ptr指向的内容修改为"H"字符串后,编译器就会报错了,因为我们说ptr的权限是只读,因为常量字符串是不可修改的,你现在进行了ptr指向内容的修改,编译器则一定会报错。
ldconfig是一个动态链接库管理命令,为了让动态链接库为系统所共享,还需运行动态链接库的管理命令–ldconfig。 ldconfig 命令的用途,主要是在默认搜寻目录(/lib和/usr/lib)以及动态库配置文件/etc/ld.so.conf内所列的目录下,搜索出可共享的动态链接库(格式如前介绍,lib*.so*),进而创建出动态装入程序(ld.so)所需的连接和缓存文件.缓存文件默认为 /etc/ld.so.cache,此文件保存已排好序的动态链接库名字列表.
python语言调用c语言进行扩展,或者增加程序的运行速度都是特别方便的。同时还能获得与C或者C++几乎相同的执行性能。
libbridge.so 动态库是 注入工具 使用 ptrace 函数强行向远程进程 注入的 动态库 , 这种方法侵入性极大 , 会破坏远程进程的运行环境 , 因此该动态库越简洁越好 ;
前段时间有人在 opentelemetry-cpp 提出了api组件在动态库中单例无法工作的 issue ,( https://github.com/open-telemetry/opentelemetry-cpp/issues/1520 ) 。
我们的动态库默认就是一个磁盘级别的文件。当我们的程序开始运行时,当程序运行到需要用到库中的实现方法时,库的代码和数据就会被加载到物理内存当中。库的实现方法一定是要跟程序运行起来所形成的进程产生关联的,动态库加载后,会被映射到该进程的地址空间中,准确来说,是先在页表中填写好对应虚拟地址和物理地址之间的映射关系,才被映射到进程地址空间中的共享区中。
编译与链接的过程可以分解为4个步骤:分别是预处理(Prepressing )、编译(Compilation )、汇编(Assembly )和链接(Linking ),一个helloworld的编译过程如下:
引言 随着越来越多功能强大的高级语言的出现,在服务器计算能力不是瓶颈的条件下,很多同学会选择开发效率高,功能强大的虚拟机支持的高级语言(Java),或者脚本语言(Python,Php)作为实现功能的首选,而不会选择开发效率低,而运行效率高的 C/C++ 作为开发语言。而这些语言一般情况下是运行在虚拟机或者解释器中,而不需要直接跟操作系统直接打交道。 虚拟机和解释器相当于为高级语言或者脚本语言提供了一个中间层,隔离了与操作系统之间进行交互的细节,这为工程师们减少了很多与系统底层打交道的麻烦,大大提高了工程师的
在Linux中,可执行文件的格式是ELF格式,而有一些命令可以帮助我们了解它们更多的“秘密”,以此来帮助我们解决问题。
先来看看程序编译和链接的过程: 编译过程又可以分成两个阶段:编译和汇编。 编译 编译是指编译器读取源程序(字符流),对之进行词法和语法的分析,将高级语言指令转换为功能等效的汇编代码。 源文件的编译过程包含两个主要阶段: 第一个阶段是预处理阶段,在正式的编译阶段之前进行。预处理阶段将根据已放置在文件中的预处理指令来修改源文件的内容。 主要是以下几方面的处理: 宏定义指令,如 #define a b 对于这种伪指令,预编译所要做的是将程序中的所有a用b替换,但作为字符串常量的 a则不被替换。还有 #undef,
C/C++程序为编译后的二进制文件,运行时载入内存,运行时内存分布由代码段、初始化数据段、未初始化数据段、堆和栈构成,如果程序使用了内存映射文件(比如共享库、共享文件),那么包含映射段。Linux环境程序典型的内存布局如图1-5所示。
所谓的SO注入就是将代码拷贝到目标进程中,并结合函数重定向等其他技术,最终达到监控或改变目标进程行为的目的。Android是基于Linux内核的操作系统,而在Linux下SO注入基本是基于调试API函数ptrace实现的,同样Android的SO注入也是基于ptrace函数,要完成注入还需获取root权限。
作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++、嵌入式、Linux。 目录 别名是啥玩意? 方法1:反向注册 方法2:嵌入汇编代码 小结 别人的经验,我们的阶梯! 别名是啥玩意? 在sta
dlsym 是 Dynamic Library Symbol 的缩写 , 该函数的作用是 根据 动态链接库 句柄 和 符号 , 返回对应 符号的地址 , 这个符号可以是方法名 , 也可以是变量名 ;
当你在Linux系统上编写和运行程序时,动态库和静态库是两个非常重要的概念。它们不仅影响着程序的编译和执行效率,还直接关系到程序的可移植性和灵活性
编程相关缩写 缩写 | 全称 | 说明 — | — | — cc | C Compiler | gcc | Gnu Compiler Collection | 作为一个软件集被你下载下来编译安装的时候 gcc | Gnu C Compiler | 作为一个软件被你调用来编译C程序的时候 g++ | Gnu c++ compiler | 其实g++只是调用gcc,然后连接c++的库,并且作相应的一些编译设置而已 gcj | Gnu Compiler for Java | gdb | Gnu DeBug |
方法一、在/etc/ld.so.conf文件中添加路径,vi /etc/ld.so.conf
1.C++特性 2.多态怎么实现的 3.可继承的类的实现需要注意什么问题(构造函数、析构函数) 4.引用和指针区别 5.const用法 6.RAII 7.函数传值、传引用、传指针区别 8.STL迭代器 9.拷贝构造函数什么时候需要重写 10.placement new 11.对象池 12.函数模板、类模板区别 13.Linux内存管理 14.Linux父进程怎么知道子进程结束了 15.进程状态有哪几个 16.守护进程创建 17.怎么查看进程 18.进程和线程区别 19.进程间通信方式 20.STL中各种容器
Cyber RT是apollo的运行环境框架,提供了模块动态加载机制。 本文基于apollo v6.0介绍Cyber RT的模块加载流程。
近日,服务器迁移后,偷懒未重新编译nginx的,直接./nginx启动,结果遇到如下问题: “error while loading shared libraries” 这是是因为需要的动态库不在动态链接器ld.so的搜索路径导致。
Android 面试涉及到底层开发总是绕不开 NDK 的,一些常见的面试题也是帮忙大家加深印象和理解!!!
so其实就是shared object的意思。今天看了上面的博客,感觉好吃力。赶紧做个笔记记录一下。下面的内容大多都是连接中的,穿插我自己的笔记
1.1 文件路径的确错误。比如:本来欲加载的是A文件夹下的动态库a.dll,但是经过仔细排查原因,发现a.dll动态库竟然被拷贝到B文件夹下去了。
Golang是静态编译型语言,在编译时就将所有引用的包(库)全部加载打包到最终的可执行程序(或库文件)中,因此并不能在运行时动态加载其他共享库。Go Plugin提供了这样一种方式,能够让你在运行时动态加载外部功能。go在1.8 支持了这个功能,类似c语言的动态链接库。
在多任务操作系统中,每个进程都运行在属于自己的内存沙盘中。这个沙盘就是虚拟地址空间(Virtual Address Space),在32位模式下它是一个4GB的内存地址块。在Linux系统中, 内核进程和用户进程所占的虚拟内存比例是1:3,而Windows系统为2:2(通过设置Large-Address-Aware Executables标志也可为1:3)。这并不意味着内核使用那么多物理内存,仅表示它可支配这部分地址空间,根据需要将其映射到物理内存。
程序运行时,内存一段连续的区域,用来保存函数运行时的状态信息,包括函数参数和局部变量
1. 在进行远程调试之前需要对Linux平台进行一些准备工作。在IDA的安装目录中的dbgsrv文件夹中,选择linux_server或者linux_serverx64复制到需要调试Linux程序所在的目录下。将复制过来的文件赋予执行权限chmod 777 linux_server*。执行该文件./linux_server或者./linux_server64。
虚拟地址空间(Virtual Address Space)是每一个程序被加载运行起来后,操作系统为进程分配的虚拟内存,它为每个进程提供了一个假象,即每个进程都在独占地使用主存。
主要简单的介绍了Mach -O和虚拟内存的知识,下文在app启动的时会有很多相关的术语,不知道会懵逼。
【引子】温故而知新,“三日不弹,手生荆棘”,代码也是如此。另一方面,自己挖的坑要自己填。在《全栈的技术栈设想》中埋下了4种编程语言的伏笔,已经兑现了Javacript,Python和Java, 本想将C/C++一并整理,但涉及面向对象等设计技术,最终还是C 梳理一下,从0到1吧。
用pthread_create创建一个线程,产生的线程ID存放在第一个参数之中,该线程ID和内核中的LWP不是一回事。pthread_create函数第一个参数指向一块虚拟内存单元,该内存单元的地址就是新创建线程ID,这个ID是线程库的范畴,而内核中LWP是进程调度的范畴,轻量级进程是OS调度的最小单位,需要一个数值来唯一标识该线程。 Linux并不提供真正的线程,只提供了LWP,但是程序员不关注LWP,只关注线程。因此,OS在OS与应用程序之间设计了一个原生线程库——pthread库。系统保存LWP,原生线程库可能存在多个线程,别人可以同时使用。OS只需要对内核执行流LWP进行管理,而提供给用户使用的线程接口等其他数据需要线程库自己来管理,线程库对线程的管理:先描述,再组织。 线程库实际上是一个动态库:
作者简介: 伟林,中年码农,从事过电信、手机、安全、芯片等行业,目前依旧从事Linux方向开发工作,个人爱好Linux相关知识分享。 原理概述 为什么要研究链接和加载?写一个小的main函数用户态程序,或者是一个小的内核态驱动ko,都非常简单。但是这一切都是在gcc和linux内核的封装之上,你只是实现了别人提供的一个接口,至于程序怎样启动、怎样运行、怎样实现这些机制你都一无所知。接着你会对程序出现的一些异常情况束手无策,对内核代码中的一些用法不能理解,对makefile中的一些实现不知所云。所以这就是我们
领取专属 10元无门槛券
手把手带您无忧上云