__attribute__((__used__)) 和 __attribute__((__section__(“*“ “*“)))的使用
见:haproxy代码
C语言注册函数和调用函数,便于模块化开发和编程。
#include <stdio.h>#ifdef __APPLE__
#define HA_SECTION(s) __attribute__((__section__("__DATA, " s)))
#define HA_SECTION_START(s) __asm("section$start$__DATA$" s)
#define HA_SECTION_STOP(s) __asm("section$end$__DATA$" s)
#else
#define HA_SECTION(s) __attribute__((__section__(s)))
#define HA_SECTION_START(s)
#define HA_SECTION_STOP(s)
#endif/** Please keep those names short enough, they are used to generate section* names, Mac OS X accepts section names up to 16 characters, and we prefix* them with i_, so stage name can't be more than 14 characters.*/
enum init_stage {STG_PREPARE = 0, // preset variables, tables, list headsSTG_LOCK, // pre-initialize locksSTG_REGISTER, // register static lists (keywords etc)STG_ALLOC, // allocate required structuresSTG_POOL, // create poolsSTG_INIT, // subsystems normal initializationSTG_SIZE // size of the stages array, must be last
};/* This is the descriptor for an initcall */
struct initcall {void (*const fct)(void *arg1, void *arg2, void *arg3);void *arg1;void *arg2;void *arg3;
#if defined(USE_OBSOLETE_LINKER)void *next;
#endif
};/* declare a symbol as global */
#define __HA_GLOBL(sym) __asm__(".globl " #sym)
#define HA_GLOBL(sym) __HA_GLOBL(sym)#define HA_INIT_SECTION(s) HA_SECTION("i_" # s)#define __DECLARE_INITCALL(stg, linenum, function, a1, a2, a3) \HA_GLOBL(__start_i_##stg ); \HA_GLOBL(__stop_i_##stg ); \static const struct initcall *__initcb_##linenum \__attribute__((__used__)) HA_INIT_SECTION(stg) = \(stg < STG_SIZE) ? &(const struct initcall) { \.fct = (void (*)(void *,void *,void *))function, \.arg1 = (void *)(a1), \.arg2 = (void *)(a2), \.arg3 = (void *)(a3), \} : NULL#define _DECLARE_INITCALL(...) \__DECLARE_INITCALL(__VA_ARGS__)#define INITCALL0(stage, function) \_DECLARE_INITCALL(stage, __LINE__, function, 0, 0, 0)/* Declare func */
#define DECLARE_INIT_SECTION(stg) \extern __attribute__((__weak__)) const struct initcall *__start_i_##stg HA_SECTION_START("i_" # stg); \extern __attribute__((__weak__)) const struct initcall *__stop_i_##stg HA_SECTION_STOP("i_" # stg)#define FOREACH_INITCALL(p,stg) \for ((p) = &(__start_i_##stg); (p) < &(__stop_i_##stg); (p)++)#define RUN_INITCALLS(stg) \do { \const struct initcall **ptr; \if (stg >= STG_SIZE) \break; \FOREACH_INITCALL(ptr, stg) \(*ptr)->fct((*ptr)->arg1, (*ptr)->arg2, (*ptr)->arg3); \} while (0)/* register func1 */
static void _do_register_func1(void)
{printf("TEST: _do_register_func1()\n");
}
#if 0
__asm__(".globl " "__start_i_STG_REGISTER");
__asm__(".globl " "__stop_i_STG_REGISTER");
static const struct initcall *__initcb_405 __attribute__((__used__)) __attribute__((__section__("i_" "STG_REGISTER"))) = (STG_REGISTER < STG_SIZE) ? &(const struct initcall)
{ .fct = (void (*)(void *,void *,void *))_do_register, .arg1 = (void *)(0), .arg2 = (void *)(0), .arg3 = (void *)(0),
} : ((void *)0);
#endif
INITCALL0(STG_REGISTER, _do_register_func1);/* register func2 */
static void _do_register_func2(void)
{printf("TEST: _do_register_func2()\n");
}
INITCALL0(STG_REGISTER, _do_register_func2);/* register func3 */
static void _do_register_func3(void)
{printf("TEST: _do_register_func3()\n");
}
INITCALL0(STG_REGISTER, _do_register_func3);/* declare func1, func2, func3 */
DECLARE_INIT_SECTION(STG_REGISTER);int main(int argc, char *const argv[])
{/* call func1, func2, func3 */RUN_INITCALLS(STG_REGISTER);printf("hello world\n");return 0;
}
编译和运行:
ubuntu@dev:test-06$ gcc test1.c
ubuntu@dev:test-06$ ./a.out
TEST: _do_register_func1()
TEST: _do_register_func2()
TEST: _do_register_func3()
hello world
不使用__attribute__((used)) 和 attribute((section(““ ““)))
#include <stdio.h>/* register func1 */
static void _do_register_func1(void)
{printf("TEST: _do_register_func1()\n");
}/* register func2 */
static void _do_register_func2(void)
{printf("TEST: _do_register_func2()\n");
}/* register func3 */
static void _do_register_func3(void)
{printf("TEST: _do_register_func3()\n");
}int main(int argc, char *const argv[])
{/* call func1, func2, func3 */_do_register_func1();_do_register_func2();_do_register_func3();printf("hello world\n");return 0;
}
相关文章:
__attribute__((__used__)) 和 __attribute__((__section__(“*“ “*“)))的使用
见:haproxy代码 C语言注册函数和调用函数,便于模块化开发和编程。 #include <stdio.h>#ifdef __APPLE__ #define HA_SECTION(s) __attribute__((__section__("__DATA, " s))) #define HA_SECTION_START(s) __asm("…...
webgoat-(A1)SQL Injection
SQL Injection (intro) SQL 命令主要分为三类: 数据操作语言 (DML)DML 语句可用于请求记录 (SELECT)、添加记录 (INSERT)、删除记录 (DELETE) 和修改现有记录 ÿ…...
Flink的API分层、架构与组件原理、并行度、任务执行计划
Flink的API分层 Apache Flink的API分为四个层次,每个层次都提供不同的抽象和功能,以满足不同场景下的数据处理需求。下面是这四个层次的具体介绍: CEP API:Flink API 最底层的抽象为有状态实时流处理。其抽象实现是Process Functi…...
Transformer:开源机器学习项目,上千种预训练模型 | 开源日报 No.66
huggingface/transformers Stars: 113.5k License: Apache-2.0 这个项目是一个名为 Transformers 的开源机器学习项目,它提供了数千种预训练模型,用于在文本、视觉和音频等不同领域执行任务。该项目主要功能包括: 文本处理:支持…...
Corel VideoStudio 会声会影2024剪辑中间的视频怎么删 剪辑中音乐太长怎么办
我很喜欢视频剪辑软件Corel VideoStudio 会声会影2024,因为它使用起来很有趣。它很容易使用,但仍然给你很多功能和力量。视频剪辑软件Corel VideoStudio 会声会影2023让我与世界分享我的想法!“这个产品的功能非常多,我几乎没有触…...
数据结构初阶---复杂度的OJ例题
复杂度的OJ例题 一、消失的数字1.思路一2.思路二3.思路三 二、旋转数组1.思路一2.思路二3.思路三 一、消失的数字 数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(N)时间内完成吗? 链接:力扣&…...
Prometheus|云原生|grafana的admin用户密码重置备忘记录
很久很久以前部署的一个Prometheus套装里的grafana密码给忘记了,回忆总是很痛苦,因此还是在这里简单的记录一下,下次就不需要满世界反翻找了。 一, 改库重置密码为admin grafana密码存放在哪里的? 必须说明一下&am…...
[hive]中的字段的数据类型有哪些
Hive中提供了多种数据类型用于定义表的字段。以下是Hive中常见的数据类型: 布尔类型(Boolean):用于表示true或false。 字符串类型(String):用于表示文本字符串。 整数类型(Intege…...
第六章 树【数据结构和算法】【精致版】
第六章 树【数据结构和算法】【精致版】 前言版权第六章 树6.1 应用实例6.2 树的概念6.2.1树的定义与表示6.2.2 树的基本术语6.2.3树的抽象数据类型定义 6.3 二叉树6.3.1二叉树的定义6.3.2 二叉树的性质6.3.3 二叉树的存储 6.4 二叉树的遍历6.4.1 二叉树的遍历及递归实现**1-二…...
第九章:Dynamic Symbolic Execution
文章目录 Dynamic Symbolic Executionoverviewmotivationdynamic symbolic execution常用的其他技术对比Random Testingsymbolic executionCombined static and symbolic - Dynamic Execution (DSE)step1: 初始化两个具体的值 x,ystep2: 根据定义得出 z 的 concrete value 和 s…...
在搜索引擎中屏蔽csdn
csdn是一个很好的技术博客,里面信息很丰富,我也喜欢在csdn上做技术笔记。 但是CSDN体量太大,文章质量良莠不齐。当在搜索引擎搜索技术问题时,搜索结果中CSDN的内容占比太多,导致难以从其他优秀的博客平台中获取信息。因…...
Linux开发工具的使用(vim、gcc/g++ 、make/makefile)
文章目录 一 :vim1:vim基本概念2:vim的常用三种模式3:vim三种模式的相互转换4:vim命令模式下的命令集- 移动光标-删除文字-剪切/删除-复制-替换-撤销和恢复-跳转至指定行 5:vim底行模式下的命令集 二:gcc/g1:gcc/g的作用2:gcc/g的语法3:预处理4:编译5:汇编6:链接7:函…...
MySQL(10):创建和管理表
基础知识 在 MySQL 中,一个完整的数据存储过程总共有 4 步,分别是:创建数据库、确认字段、创建数据表、插入数据。 要先创建一个数据库,而不是直接创建数据表:从系统架构的层次上看,MySQL 数据库系统从大到…...
Python赋值给另一个变量且不改变原变量
Python赋值给另一个变量且不改变原变量 在Python中,如果你想将一个变量的值赋给另一个变量,同时保持原变量不变,你可以使用复制(copy)而不是引用(reference)。Python中的变量通常是通过引用&…...
PHP进销存ERP系统源码
PHP进销存ERP系统源码 系统介绍: 扫描入库库存预警仓库管理商品管理供应商管理。 1、电脑端手机端,手机实时共享,手机端一目了然。 2、多商户Saas营销版 无限开商户,用户前端自行注册,后台管理员审核开通 3、管理…...
npm i 报错:Cannot read properties of null (reading ‘refs‘)
问题: 旧项目要更改东西,重新部署上线的时候,发现页面显示有异常。当时在开发环境是没有问题的。后经排查是一个引入swiper的页面报错了,只要注释掉swiper插件,就没问题了,但这肯定是不行的。 原因: npm和…...
C#学习中关于Visual Studio中ctrl+D快捷键(快速复制当前行)失效的解决办法
1、进入VisualStudio主界面点击工具——>再点击选项 2、进入选项界面后点击环境——>再点击键盘,我们可用看到右边的界面的映射方案是VisualC#2005 3、 最后点击下拉框,选择默认值,点击之后确定即可恢复ctrlD的快捷键功能 4、此时可以正…...
银河E8,吉利版Model 3:5米大车身、45寸大屏、首批8295座舱芯
作者 | Amy 编辑 | 德新 吉利银河E8在曝光后多次引爆热搜,李书福更是赞誉有加,称其为「买了就直接享受」。这款备受瞩目的车型于 10月30日晚首次亮相。 虽然新车外观在今年上海车展上早已曝光,但这次的发布会却带来了不少惊喜。新车架构以及…...
技术分享 | 被测项目需求你理解到位了么?
需求分析是开始测试工作的第一步,产品会先产出一个需求文档,然后会组织需求宣讲,在需求宣讲中分析需求中是否存在问题,然后宣讲结束后,通过需求文档分析测试点并且预估排期。所以对于需求的理解非常重要。 需求文档 …...
[MRCTF2020]你传你呢1
提示 只对php以及phtml文件之类的做了防护content-type.htaccess文件 这里就不整那么麻烦直接抓包测试 首先对后缀测试看过滤了哪些 (php php3 pht php5 phtml phps) 全部被ban了 到这里的后续思路通过上传一些配置文件把上传的图片都以php文件执行 尝试上传图片码, 直接上传成…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
深入浅出:JavaScript 中的 `window.crypto.getRandomValues()` 方法
深入浅出:JavaScript 中的 window.crypto.getRandomValues() 方法 在现代 Web 开发中,随机数的生成看似简单,却隐藏着许多玄机。无论是生成密码、加密密钥,还是创建安全令牌,随机数的质量直接关系到系统的安全性。Jav…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
什么是库存周转?如何用进销存系统提高库存周转率?
你可能听说过这样一句话: “利润不是赚出来的,是管出来的。” 尤其是在制造业、批发零售、电商这类“货堆成山”的行业,很多企业看着销售不错,账上却没钱、利润也不见了,一翻库存才发现: 一堆卖不动的旧货…...
Matlab | matlab常用命令总结
常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...
动态 Web 开发技术入门篇
一、HTTP 协议核心 1.1 HTTP 基础 协议全称 :HyperText Transfer Protocol(超文本传输协议) 默认端口 :HTTP 使用 80 端口,HTTPS 使用 443 端口。 请求方法 : GET :用于获取资源,…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...
LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...
图解JavaScript原型:原型链及其分析 | JavaScript图解
忽略该图的细节(如内存地址值没有用二进制) 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么:保存在堆中一块区域,同时在栈中有一块区域保存其在堆中的地址(也就是我们通常说的该变量指向谁&…...
