strong_alias && weak_alias && __attribute__

2023-05-16

 

 

为了查看linux下malloc的实现函数,下载了Glibc的源码文件,可是找不到实现的函数在哪里。

看文件名 应该是在malloc/malloc.c里面。

 

发现__libc_malloc的实现比较像。

 

怎么从malloc到__libc_malloc的呢?

 

看到文件里有一个语句

image

有点苗头

 

来看看strong_alias的实现

image

_typeof (name) aliasname 就是定义别名的意思了 至于后面的__attribute__看下面的解释。

 

GNU C的一大特色(却不被初学者所知)就是__attribute__机制。

__attribute__可以设置函数属性(Function Attribute)、变量属性(Variable Attribute)和类型属性(Type Attribute)

__attribute__前后都有两个下划线,并且后面会紧跟一对原括弧,括弧里面是相应的__attribute__参数

__attribute__语法格式为:

__attribute__ ( ( attribute-list ) )

函数属性(Function Attribute),函数属性可以帮助开发者把一些特性添加到函数声明中,从而可以使编译器在错误检查方面的功能更强大。

__attribute__机制也很容易同非GNU应用程序做到兼容。

GNU CC需要使用 –Wall,这是控制警告信息的一个很好的方式。

 

就这样定义了malloc的是__libc_malloc的别名,__malloc也是__libc_malloc的别名。

__attribute__((alias)) variable attribute

This variable attribute enables you to specify multiple aliases for variables.

Where a variable is defined in the current translation unit, the alias reference is replaced by a reference to the variable, and the alias is emitted alongside the original name. Where a variable is not defined in the current translation unit, the alias reference is replaced by a reference to the real variable. Where a variable is defined as static, the variable name is replaced by the alias name and the variable is declared external if the alias is declared external.

Note

Function names might also be aliased using the corresponding function attribute __attribute__((alias)).

Show/hideSyntax
type newname __attribute__((alias("oldname")));

Where:

oldname

is the name of the variable to be aliased

newname

is the new name of the aliased variable.

Show/hideExample

#include <stdio.h>
int oldname = 1;
extern int newname __attribute__((alias("oldname"))); // declaration
void foo(void)
{  

    printf("newname = %d\n", newname); // prints 1
}  

image

 

还存在一种weak_alias的概念,对比strong_alias,就是展开的时候多了个__attribute__里多了个weak

 

alias:表示当前符号是另外一个(目标target)符号的别称。比如:

void __f () { /* Do something. */; }

void f () __attribute__ ((weak, alias ("__f")));

 

alias修饰的是符号f,指定的目标符号是__f,也就是说符号f是符号__f的别称。

weak:表示当前符号是个弱类型符号(weak symbol),而非全局符号。看个示例:
1,首先,准备一个库文件(以静态库为例,后文将提到为什么不以动态库为例):

[root@localhost weak_test1]# cat /etc/issue

CentOS release 6.2 (Final)

Kernel \r on an \m

[root@localhost weak_test1]# uname -a

Linux localhost.localdomain 2.6.32-220.el6.i686 #1 SMP Tue Dec 6 16:15:40 GMT 2011 i686 i686 i386 GNU/Linux

[root@localhost weak_test1]# vi mylib.c

[root@localhost weak_test1]# cat !$

cat mylib.c

#include <stdio.h>

void foo()

{

printf("lib test\n");

}

void foo() __attribute__ ((weak));

[root@localhost weak_test1]# <span class="wp_keywordlink_affiliate"><a href="http://lenky.info/tag/gcc/" title="查看 gcc 中的全部文章">gcc</a></span> -c mylib.c

[root@localhost weak_test1]# ar crv libmylib.a mylib.o

a - mylib.o

可以看到libmylib.a库里定义了一个函数foo(),并且是weak弱类型。

2,编写一个应用程序(由两个源文件myapp.c与myfoo.c构成):

[root@localhost weak_test1]# vi myapp.c

[root@localhost weak_test1]# cat !$

cat myapp.c

#include <stdio.h>

int main()

{

foo();

return 0;

}

[root@localhost weak_test1]# vi myfoo.c

[root@localhost weak_test1]# cat !$

cat myfoo.c

#include <stdio.h>

void foo()

{

printf("app test\n");

}

源文件myfoo.c调用的foo()函数可以来自libmylib.a库,也可以来自应用程序的另外一个源文件,连接并执行:

[root@localhost weak_test1]# gcc myapp.c myfoo.c libmylib.a -o myapp_weak

[root@localhost weak_test1]# ./myapp_weak

app test

打印显示的是app test,即调用的是应用程序自身的函数foo()。

3,如果应用程序本身不提供函数foo(),那么情况是怎样:

[root@localhost weak_test1]# gcc myapp.c libmylib.a -o myapp

[root@localhost weak_test1]# ./myapp

lib test

打印显示的是lib test,即调用了libmylib.a库里的weak弱类型函数foo()。

4,试试去掉库里的weak修饰:

[root@localhost weak_test1]# vi mylib.c

[root@localhost weak_test1]# cat mylib.c

#include <stdio.h>

void foo()

{

printf("lib test\n");

}

//void foo() __attribute__ ((weak));

[root@localhost weak_test1]# gcc -c mylib.c;ar crv libmylib.a mylib.o

r - mylib.o

[root@localhost weak_test1]# gcc myapp.c myfoo.c libmylib.a -o myapp

[root@localhost weak_test1]# ./myapp

app test

去掉weak修饰后也没问题?那weak属性到底有啥用?试试把libmylib.a放前面:

[root@localhost weak_test1]# gcc myapp.c libmylib.a myfoo.c -o myapp

/tmp/ccIjvazY.o: In function `foo':

myfoo.c:(.text+0x0): multiple definition of `foo'

libmylib.a(mylib.o):mylib.c:(.text+0x0): first defined here

collect2: ld returned 1 exit status

[root@localhost weak_test1]# gcc libmylib.a myapp.c myfoo.c -o myapp

[root@localhost weak_test1]# gcc libmylib.a myfoo.c myapp.c -o myapp

[root@localhost weak_test1]# gcc myfoo.c libmylib.a myapp.c -o myapp

[root@localhost weak_test1]# gcc myfoo.c myapp.c libmylib.a -o myapp

对比一下,加上weak修饰:

[root@localhost weak_test1]# vi mylib.c

[root@localhost weak_test1]# cat mylib.c

#include <stdio.h>

void foo()

{

printf("lib test\n");

}

void foo() __attribute__ ((weak));

[root@localhost weak_test1]# gcc -c mylib.c;ar crv libmylib.a mylib.o

r - mylib.o

[root@localhost weak_test1]# gcc myapp.c libmylib.a myfoo.c -o myapp

[root@localhost weak_test1]# gcc libmylib.a myapp.c myfoo.c -o myapp

[root@localhost weak_test1]# gcc libmylib.a myfoo.c myapp.c -o myapp

[root@localhost weak_test1]# gcc myfoo.c libmylib.a myapp.c -o myapp

[root@localhost weak_test1]# gcc myfoo.c myapp.c libmylib.a -o myapp

[root@localhost weak_test1]# ./myapp

app test

去掉weak修饰后,只有一个杯具的报错了,难道是和库文件排放位置相关?不用库函数,直接用源代码试试:

[root@localhost weak_test1]# vi mylib.c

[root@localhost weak_test1]# cat mylib.c

#include <stdio.h>

void foo()

{

printf("lib test\n");

}

//void foo() __attribute__ ((weak));

[root@localhost weak_test1]# gcc myapp.c myfoo.c mylib.c -o myapp

/tmp/ccbKVCYU.o: In function `foo':

mylib.c:(.text+0x0): multiple definition of `foo'

/tmp/cc3DKEyS.o:myfoo.c:(.text+0x0): first defined here

collect2: ld returned 1 exit status

[root@localhost weak_test1]# gcc myapp.c mylib.c myfoo.c -o myapp

/tmp/ccosX9JJ.o: In function `foo':

myfoo.c:(.text+0x0): multiple definition of `foo'

/tmp/ccyyg6us.o:mylib.c:(.text+0x0): first defined here

collect2: ld returned 1 exit status

报错(必然的),加上:

[root@localhost weak_test1]# vi mylib.c

[root@localhost weak_test1]# cat mylib.c

#include <stdio.h>

void foo()

{

printf("lib test\n");

}

void foo() __attribute__ ((weak));

[root@localhost weak_test1]# gcc myapp.c myfoo.c mylib.c -o myapp

[root@localhost weak_test1]# gcc myapp.c mylib.c myfoo.c -o myapp

啥结论?看来weak修饰符的原本含义是让weak弱类型的函数可以被其它同名函数覆盖(即不会发生冲突),如果没有其它同名函数,就使用该weak函数,类似于是默认函数;
但是,受到“库”这一特别存在的影响,weak弱类型对库变得“不太可靠”了,而且根据Weak definitions aren’t so weak来看,对于新版本的glibc,weak修饰符仅针对静态库产生影响。

转载于:https://www.cnblogs.com/justinyo/archive/2013/03/12/2956438.html

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

strong_alias && weak_alias && __attribute__ 的相关文章

  • Oracle 列别名中的双引号

    好吧 这是一个有点晦涩的问题 但希望有人能帮助我解决这个问题 我正在开发的系统构建了一个用于在存储过程中执行的动态 SQL 字符串 以及定义列别名的动态 SQL 的一部分 这些别名本身实际上是从用户生成的数据的另一个表中检索的值 因此 例如
  • 找不到模块,webpack 别名与 typescript React

    我正在尝试在 webpack 中实现一些别名 我想要做的是 不要使用它从组件文件夹导入 App js 上的组件 components layout Header Header 我要这个 components layout Header He
  • 如何使用 System.DirectoryServices.ActiveDirectory.Domain 类获取域别名

    我们有一个完整的域名 例如长域名 com 该域名已替换为别名short 可以使用以下命令检索此别名netapi32 dll 像这样 DllImport Netapi32 dll static extern int NetApiBufferF
  • 如何在 Java 中创建一些变量类型别名

    假设我有这个代码 Map
  • 如何给函数起别名?

    我正在尝试为 R 中的函数创建别名 例如 要获取 R 中向量的长度 length the vector returns the length of the vector 我想创建一个名为 len 的函数的别名 len the vector
  • Yii2:活动记录列别名

    我正在使用 Yii2 框架和高级模板 我的控制器文件中的列别名出现问题 这是我的代码 models new ActiveDataProvider query gt User find gt select member gt fullname
  • java泛型协方差

    我无法理解以下文章 http www ibm com developerworks java library j jtp01255 html https web archive org web 20161204181636 https ww
  • 在不违反标准的情况下使用指向结构的指针对数组进行别名

    Reading this http cellperformance beyond3d com articles 2006 06 understanding strict aliasing html我理解 如果结构具有兼容的成员 则可以为结构
  • 如何在 OSX 中的 .bash_profile 中获取外部文件?

    我在我的中定义了一些别名 bash profile文件和别名按预期工作 例如 alias python server python m SimpleHTTPServer 7070 而且 当我打开新终端时 输入python server打开一
  • 为 git log 这样的两个字命令创建别名?

    有时我有两个词的命令 例如git log or apt get install我想添加一个默认参数 例如 大多数时候我想添加 abbrev commit参数给我的git log 以及 y参数为apt get install git log
  • Powershell 删除项目无法从函数中运行

    我需要将别名 cd 替换为名为 cd 的函数 我尝试从函数中删除别名 但没有成功 以下是一个简单的测试脚本 function remove alias get command cd Remove Item Path Alias cd get
  • Tomcat 上的 SSL 证书 - 别名无法识别密钥

    想知道是否有人可以告诉我我在哪里搞砸了 我有一个 keytool 创建的密钥库 一个来自 Thawte 的主证书 辅助证书和 ssl 证书 我最初使用 openssl 创建了 CSR 然后使用记录的过程将私钥转换为 PKCS12 以导入到密
  • 在 Cypress 中多次拦截相同的 API 调用

    是否可以使用cy intercept在同一个测试中多次拦截相同的 API 调用 我尝试了以下方法 cy intercept pathname url method POST as call1 some logic cy wait call1
  • 动态为mysql查询中的所有字段名分配别名

    我的 mysll 数据库中有 2 个表 两个表都有很少的固定列和很少的动态列 字段 架构 我想用以下查询连接这两个表 SELECT FROM cd cd LEFT JOIN cd n cn ON cd id cn fk cd 我想要的结果是
  • 最少输入命令行计算器 - tcsh 与 bash

    我喜欢有一个方便的命令行计算器 要求是 支持所有基本算术运算符 用于求幂 加上括号用于分组 需要最少的输入 我不想调用一个程序与之交互 然后要求它退出 理想情况下 除了表达式本身之外 命令行中只应输入一个字符和一个空格 它应该知道如何忽略逗
  • 如何为ubuntu创建永久“别名”? [复制]

    这个问题在这里已经有答案了 例如 如果您创建别名 alias cls clear 它一直存在 直到您终止终端会话为止 当您启动新的终端窗口时 别名不再存在 如何创建 永久 别名 该别名存在于每个终端会话中 您可以将此类别名放入 bash a
  • C# 中的 String 和 string 有什么区别?

    这两者之间有什么区别 我应该使用哪一个 string s Hello world String s Hello world string https learn microsoft com en us dotnet csharp langu
  • 使用通配符在 .zshrc 中获取多个文件

    我通过 oh my zsh 使用 z shell 我想从 zshrc 文件中获取多个别名文件 这样我就可以让事情井井有条 我已经为别名文件添加了前缀 alias 这样我就可以通配符加载它们 但是 打电话给source alias 只加载第一
  • bash 函数保留制表符补全

    我把函数 make color make 1 ccze A in bashrc获得彩色的 make 输出 他的作品很好 但是make用于选择目标的制表符补全功能丢失 有什么方法可以保留函数中命令的制表符完成 或者我可以做其他事情来实现制表符
  • 如何在jOOQ中使用别名

    有人可以指导我如何在 jOOQ 中使用别名吗 我尝试查看 jOOQ 文档 但不清楚 如果可能 请提供示例 Both org jooq Table http www jooq org javadoc latest org jooq Table

随机推荐

  • haproxy 配置详解

    说明 xff1a 1 haproxy的配置段有 34 global 34 xff0c 34 defaults 34 34 listen 34 34 frontend 34 和 34 backend 34 等 global 配置中的参数为进程
  • 什么是灰度图

    为什么80 的码农都做不了架构师 xff1f gt gt gt 图像灰度值的概念是什么 xff1f 灰度也可以认为是亮度 xff0c 简单说就是色彩的深浅程度 实际上在我们的日常生活中 xff0c 通过三原色色彩深浅的组合 xff0c 可以
  • matlab figure 窗口最大化

    http blog 163 com yinhexiwen 64 126 blog static 6404826620122942057214 figure 窗口最大化 xff0c 坐标轴也随着窗口变大而相应变大 scrsz 61 get 0
  • 让Tomcat7识别War包的Class-Path(MANIFEST.MF)属性动态加载类路径

    原文 https my oschina net noahxiao blog 173499 目录 一 背景 二 分析 三 开发 四 总结 一 背景 几个Web项目需要打包到一个发布包中 xff0c 问题是War包都各自包含了自己的WEB IN
  • 【黑马程序员】————结构体

    Java培训 Android培训 iOS培训 Net培训 期待与您交流 xff01 一 什么是结构体 数组 xff1a 只能由多个相同类型的数据构成 结构体 xff1a 可以由多个不同类型的数据构成 二 结构体的定义 1 定义形式 结构体内
  • 《oracle大型数据库系统在AIX/unix上的实战详解》讨论28:两台机器间Oracle迁移的方法和过程...

    oracle大型数据库系统在AIX unix上的实战详解 讨论28 xff1a 两台机器间Oracle迁移的方法和过程 文平 大家新年好 xff01 新年期间没有更新日志 xff0c 也没有查收大家发来的邮件 今天回到工作岗位 xff0c
  • 《Programming in Lua 3》读书笔记(十六)

    日期 xff1a 2014 7 23 Part The Standard Libraries 20 The Table Library table库包含一些辅助函数用以类似与数组一样操作table 提供了从list内插入和删除元素的操作 x
  • 重磅系列文章|UI2Code智能生成Flutter代码--整体设计篇 ...

    闲鱼技术 上叶 背景 随着移动互联网时代的到来 xff0c 人类的科学技术突飞猛进 然而软件工程师们依旧需要花费大量精力在重复的还原UI视觉稿的工作 UI视觉研发拥有明显的特征 xff1a 组件 xff0c 位置和布局 xff0c 符合机器
  • linux debian系统卸载jdk,Debian/Ubuntu系统 JDK卸载、安装、环境配置

    环境 xff1a Linux内核版本4 17 Oracle jdk 11 0 2 JDK 8同样也是设置 Debian9系统 注意 xff1a 1 Open JDK和Oracle JDK的安装过程只是下载的连链接不一样 2 有的Linux系
  • MySQL 8.0 Windows zip 安装过程

    2019独角兽企业重金招聘Python工程师标准 gt gt gt 准备 xff1a MySQL8 0 Windows zip包下载地址 xff1a https cdn mysql com Downloads MySQL 8 0 mysql
  • nohup后台执行脚本并输入日志到指定目录 &

    后台执行命令 xff0c 并输出目录到指定目录 root 64 localhost smgpSend Log nohup tar zcvf sendThread bak tar sendThread bak gt gt 1 txt amp
  • 在 Laravel 5 中集成七牛云存储实现云存储功能

    本扩展包基于https github com qiniu php sdk 开发 xff0c 是七牛云储存 Laravel 5 Storage版 xff0c 通过本扩展包可以在Laravel 5中集成七牛云存储功能 1 安装配置 使用之前 x
  • BSS段、数据段、代码段、堆与栈

    BSS段 xff1a BSS段 xff08 bss segment xff09 通常是指用来存放程序中未初始化的全局变量的一块内存区域 BSS是英文Block Started by Symbol的简称 BSS段属于静态内存分配 数据段 xf
  • Java字符串排序中文+数字

    编写日期 xff1a 2013年9月15日 另一中解法 xff1a 点击查看 解决思路 xff1a 在Java中 xff0c 排序需要复写的是 equals 方法 和 Comparable lt T gt 接口 的public int co
  • UIView 中常见的方法总结

    addSubview 添加一个子视图到接收者并让它在最上面显示出来 void addSubview UIView view 讨论 这方法同样设置了接收者为下一个视图响应对象 接收者保留视图 如果你使用removeFromSuperview方
  • docker方式部署gitlab

    docker方式部署gitlab 说明 操作系统 CentOS Linux release 7 9 2009 Core docker版本 20 10 17主机ip地址 172 16 100 107gitlab cn官网安装教程 https
  • iOS libc++abi.dylib: handler threw exception 错误的解决方案

    简单说下背景 xff1a 最近把工具和SDK都进行了升级Xcode4 5和iOS6 xff0c 无意之中测出了一个 必现的bug xff1a libc 43 43 abi dylib handler threw exception libc
  • 后羿射日般的精准 - 阿里云ECS调度是如何炼成的

    1 引子 弹性计算服务ECS xff08 Elastic Compute Service xff09 是阿里云营收的中流砥柱和流量担当 作为各行业客户新业务和技术创新的发动机和使能者 xff0c ECS不仅能在10分钟内交付出一个中等体量互
  • java每日小算法(12)

    程序12 题目 xff1a 企业发放的奖金根据利润提成 利润 I 低于或等于10万元时 xff0c 奖金可提10 xff1b 利润高于10万元 xff0c 低于20万元时 xff0c 低于10万元的部分按10 提成 xff0c 高于10万元
  • strong_alias && weak_alias && __attribute__

    为了查看linux下malloc的实现函数 xff0c 下载了Glibc的源码文件 xff0c 可是找不到实现的函数在哪里 看文件名 应该是在malloc malloc c里面 发现 libc malloc的实现比较像 怎么从malloc到