带你走进Cflow (三)·控制符号类型分析

目录

​编辑

1、控制符号类型

1.1  语法类

1.2  符号别名

1.3  GCC 初始化


1、控制符号类型

        有人也许注意到了输出中奇怪的现象:函数_exit 丢失了,虽然它在源文件中被printdir 调用了两次。这是因为默认情况下 cflow 忽略所有的一下划线开头的符号。为了将这样的符号包含进来,我们使用-i _ (or --include _)命令行选项。继续我们的例子:

$ cflow --number -i _ d.c
 1 main() <int main (int argc,char **argv) at d.c:85>:
 2 fprintf()
 3 atoi()
 4 printdir() <void printdir (int level,char *name) at d.c:42> (R):
 5 getcwd()
 6 perror()
 7 _exit()
 8 chdir()
 9 opendir()
 10 readdir()
 11 printf()
 12 ignorent() <int ignorent (char *name) at d.c:28>:
 13 strcmp()
 14 isdir() <int isdir (char *name) at d.c:12>:
 15 stat()
 16 perror()
 17 S_ISDIR()
 18 putchar()
 19 printdir()
 <void printdir (int level,char *name) at d.c:42>
 (recursive: see 4)
 20 closedir()

        通常情况下,参数--include 制定了一个符号类列表。默认的选项行为是输出中包含被请求的类。如果参数是以减号或插入符号开始的,则处理方式正好相反,是在输出结果中排除这种符号类。

        符号类‘_’包含了所有已下划线开头的符号。另一个有用的符号类是’s’,它表示静态函数或数据。默认情况下,静态函数是被包含在输出中的。为了省略他们,可以使用所给的-i ^s (or -i -s)选项。我们的样例程序 d.c 中定义了静态函数 isdir,运行 cflow -i ^s,可以在结果图中完全忽略这个函数和它的调用者。

$ cflow --number -i ^s d.c
 1 main() <int main (int argc,char **argv) at d.c:85>:
 2 fprintf()
 3 atoi()
 4 printdir() <void printdir (int level,char *name) at d.c:42> (R):
 5 getcwd()
 6 perror()
 7 chdir()
 8 opendir()
 9 readdir()
 10 printf()
 11 ignorent() <int ignorent (char *name) at d.c:28>:
 12 strcmp()
 13 putchar()
 14 printdir()
 <void printdir (int level,char *name) at d.c:42>
 (recursive: see 4)
 15 closedir()

        实际上,非包含符号(‘^’ 或 ‘-’)可以在-i 的参数中的任何地方使用,不仅限于开始。因此,选项-i _^s 表示包含除了静态函数以外的以下划线开头的符号。-i 选项可以累积使用,所以这个例子可以写为-i _ -i ^s。

        一个很重要的一点是,默认情况下 cflo 图中只包含函数。然而你可以使用符号类“x”来将变量输出。这个类包含所有的数据符号,包括全局变量和静态变量。如下例:

$ cflow --number -i x d.c
 1 main() <int main (int argc,char **argv) at d.c:85>:
 2 fprintf()
 3 stderr
 4 max_level <int max_level at d.c:37>
 5 atoi()
 6 printdir() <void printdir (int level,char *name) at d.c:42> (R):
 7 DIR
 8 dir
 9 getcwd()
 10 perror()
 11 chdir()
 12 opendir()
 13 readdir()
 14 printf()
 15 ignorent() <int ignorent (char *name) at d.c:28>:
 16 ignored_names <char *ignored_names[] at d.c:24>
 17 strcmp()
 18 isdir() <int isdir (char *name) at d.c:12>:
 19 stat()
 20 perror()
 21 S_ISDIR()
 22 NULL
 23 max_level <int max_level at d.c:37>
 24 putchar()
 25 printdir()
 <void printdir (int level,char *name) at d.c:42>
 (recursive: see 6)
 26 closedir()

        现在,第 3、4、16、23 行显示了数据标号,同时显示了可用的定义。然而请注意第 7、8 行。为什么类型名 DIR 和自动变量 dir 也被作为数据列出?为了回答这个问题,我们首先描述一线 cflow 对符号的概念定义。程序维持着符号表,使用 C 语言预处理关键字初始化。当解析输入文件时,cflow 更新了这些表。特别的,当遇到一个 typedef 时,它就将这个定义符号注册为数据类型。现在,DIR 在 d.c 中没有声明,所以 cflow 无法知道这是一个数据类型。所以他认为这是一个变量,这样一来输入:DIR *dir;就被解析为一个表达式,意思是“DIR乘以 dir”。

        当然这是错误的。有两种方式可以帮助 cflow 排除这种混淆。要么详细的声明 DIR为一个数据类型,要么让 cflow 运行预处理器,这样一来 cflow 就能看到头文件的内容,并自己做出决定。运行预处理器在下一章中。这一章我们主要集中精力在第一种方法。

        命令行选项--symbol (-s)声明这个符号的语法类。这个参数包含了被冒号隔开的两个字符串:--symbol sym:class。

        第一个字符串,sym 是 C 语言的符号表的识别码。第二个字符串,class,指定了与这个符号结合的类。特别的如果 class 是‘type’,那么符号 sym 就被记录为 C 语言类型定义。因此,修改上面的输出,运行:

$ cflow --number -i x --symbol DIR:type d.c

        另一个重要的符号类型是参数包装,这是宏的一种,经常用于兼容 ANSI 之前的编 译 器 来 保 护 函 数 原 型 中 的 参 数 声 明 的 源 。 比 如 下 面 的 声 明 , 从/usr/include/resolv.h 中获得,其中__P 是参数包装:

void res_npquery __P((const res_state, const u_char *, int, FILE *));

        为了能让 cflow 处理这样的声明,声明__P 为一个包装,例如:

cflow --symbol __P:wrapper *.c

        在所有的必须使用--symbol 选项的例子中,都是 cflow 不能识别给定的符号的意义,这要么是因为 cflow 不能看到类型的定义,就像‘DIR’的例子;要么是因为宏定义没有展开。这两种情况都可以用下一章藐视的预处理模式来解决。虽然有了预处理模式,但--symbol 选项还是有用的,我们会在下面的一节中看到:

1.1  语法类

总的来说,符号定义的语法类在 C 语言代码中是可以合法存在的。有如下的类:

关键字;关键字,比如‘if’、‘when’等

修改器;类型修改器,比如这个符号在数据类型后出现,可以修改数据的意义,比如指针‘*’。

修饰符;声明修饰符。能在 C 数据类型的前面和后面声明。你也许会经常声明gcc 关键字‘__extension__’作为修饰符:--symbol __extension__:qualifier

识别码;C 语言识别码。

类型;C 语言数据类型,比如‘char’,’int’。

包装器;他有两个用途,第一个是当没有运行预处理的时候声明一个参数包装器。这种用法在前面已经声明了。第二种,他表示任何能出现在声明符前或作为结尾的分号之前和后面可以跟一个括号表达式列表中的任何符号。

我们建议这样对 gcc 使用这个类:‘__attribute__’。

1.2  符号别名

        另一个--symbol 选项的用法是定义符号别名。别名是一个与被它引用的符号完全一样的标识。别名可以这样声明:--symbol newsym:=oldsym这样一来,符号 newsym 就被声明为和 oldsym 完全一样的类型了。

        符号别名也能在其他例子中作为定义符号类使用。对一些特殊的关键字是非常有用的,例如‘__restrict’: --symbol __restrict:=restrict。

1.3  GCC 初始化

下面的引用集是使用 gcc 时 cflow 的初始化选项。我们建议将他们放到 cflow.rc文件中:

--symbol __inline:=inline
 --symbol __inline__:=inline
 --symbol __const__:=const
 --symbol __const:=const
 --symbol __restrict:=restrict
 --symbol __extension__:qualifier
 --symbol __attribute__:wrapper
 --symbol __asm__:wrapper
 --symbol __nonnull:wrapper
 --symbol __wur:wrapper

带你走进Cflow (一)-CSDN博客

带你走进Cflow (二)·输出格式和递归调用-CSDN博客

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/130262.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

gird 卡片布局

场景一&#xff1a;单元格大小相等 这承载了所有 CSS Grid 中最著名的片段&#xff0c;也是有史以来最伟大的 CSS 技巧之一&#xff1a; 等宽网格响应式卡片实现 .section-content {display: grid;grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));gap: 10px; …

ros1 基础学习09 -自定义service服务开发示例

自定义service服务开发示例 如何使用服务一、模型图二、创建功能包三、自定义服务数据3.1 在package.xml中添加功能包依赖3.2 在CmakeLists.txt中添加编译选项3.3 编译生成的C文件和Python库4.1.2 编译整个工作空间 测试&#xff1a; 在ROS中&#xff0c;除了消息这种通信类型外…

Python爬虫——入门爬取网页数据

目录 前言 一、Python爬虫入门 二、使用代理IP 三、反爬虫技术 1. 间隔时间 2. 随机UA 3. 使用Cookies 四、总结 前言 本文介绍Python爬虫入门教程&#xff0c;主要讲解如何使用Python爬取网页数据&#xff0c;包括基本的网页数据抓取、使用代理IP和反爬虫技术。 一、…

git命令之遭遇 ignore罕见问题解决

我先来讲讲背景 我的一些文件在ignore了&#xff0c;不会被提交到远程仓库&#xff0c;这时候我的远程仓库中是没有这几个文件的&#xff0c;这时候我如果使用 git reset 的话这时候除了那几个 ignore 的文件以外都被更新的&#xff0c;但是如果我不需要这几个被 ignore 的文件…

[Machine Learning] 多任务学习

文章目录 基于参数的MTL模型 (Parameter-based MTL Models)基于特征的MTL模型 (Feature-based MTL Models)基于特征的MTL模型 I&#xff1a;基于特征的MTL模型 II&#xff1a; 基于特征和参数的MTL模型 (Feature- and Parameter-based MTL Models) 多任务学习 (Multi-task Lear…

千帆SDK开源到GitHub,开发者可免费下载使用!

目录 一、SDK的优势 二、千帆SDK&#xff1a;快速落地LLM应用 三、如何快速上手千帆SDK 1、SDK快速启动 快速安装 平台鉴权 如何获取AK/SK 以“Chat 对话”为调用示例 2. SDK进阶指引 3. 通过Langchain接入千帆SDK 为什么选择Langchain 开源社区 千帆社区 好消息&…

高斯过程回归 | GPR高斯过程回归

高斯过程回归(Gaussian Process Regression, GPR)是一种强大的非参数回归方法,它通过假设数据是从一个高斯过程中生成的来预测新的数据点。 高斯过程是一种定义在连续输入空间上的随机过程,其中任何有限集合的观测值都呈多变量高斯分布。 实现GPR的Python代码import numpy …

Redis快速入门

1.说说什么是Redis? Redis 是互联网技术领域中使用最广泛的存储中间件&#xff0c;它是 Remote Dictionary Service 三个单词中加粗字母的组合。你别说&#xff0c;组合起来后念着挺自然的。 Redis 以超高的性能、完美的文档、简洁的源码著称&#xff0c;国内外很多大型互联网…

在GORM中使用并发

一个全面的指南&#xff0c;如何安全地使用GORM和Goroutines进行并发数据处理 效率是现代应用程序开发的基石&#xff0c;而并发在实现效率方面发挥着重要作用。GORM&#xff0c;这个强大的Go对象关系映射库&#xff0c;使开发人员能够通过Goroutines embrace并行性。在本指南…

FPGA UDP RGMII 千兆以太网(3)ODDR

1 xilinx原语 在 7 系列 FPGA 中实现 RGMII 接口需要借助 5 种原语,分别是:IDDR、ODDR、IDELAYE2、ODELAYE2(A7 中没有)、IDELAYCTRL。其中,IDDR和ODDR分别是输入和输出的双边沿寄存器,位于IOB中。IDELAYE2和ODELAYE2,分别用于控制 IO 口输入和输出延时。同时,IDELAYE2 …

SPSS曲线回归

前言&#xff1a; 本专栏参考教材为《SPSS22.0从入门到精通》&#xff0c;由于软件版本原因&#xff0c;部分内容有所改变&#xff0c;为适应软件版本的变化&#xff0c;特此创作此专栏便于大家学习。本专栏使用软件为&#xff1a;SPSS25.0 本专栏所有的数据文件请点击此链接下…

【PWN · ret2csu】[HNCTF 2022 WEEK2]ret2csu

记一道ret2csu 一、题目 二、思路 1.ret2csu用write泄露write的真实地址->泄露libc->获得system的真实地址 2.ret2csu用read写/bin/sh字符串到bss段上 3.ret2csu用write将system的真实地址写到bss段上 4.ret2csu调用system 三、exp from pwn import * from pwn impo…

LeetCode(2)移除元素【数组/字符串】【简单】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 27. 移除元素 1.题目 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原…

后端架构选择:构建安全强大的知识付费小程序平台

构建知识付费小程序平台需要考虑后端架构&#xff0c;确保系统安全性、性能和可扩展性。以下是一些常见的后端技术和最佳实践&#xff0c;能帮助您构建强大且安全的知识付费小程序平台。 1. 服务器端语言和框架选择 选择流行、成熟的后端语言和框架&#xff0c;如Node.js、P…

机器学习---多分类SVM、支持向量机分类

1. 多分类SVM 1.1 基本思想 Grammer-singer多分类支持向量机的出发点是直接用超平面把样本空间划分成M个区域&#xff0c;其 中每个区域对应一个类别的输入。如下例&#xff0c;用从原点出发的M条射线把平面分成M个区域&#xff0c;下图画 出了M3的情形&#xff1a; 1.2 问题…

EXPLAIN详解(MySQL)

EXPLAIN概述 EXPLAIN语句提供MySQL如何执行语句的信息。EXPLAIN与SELECT, DELETE, INSERT, REPLACE和UPDATE语句一起工作。 EXPLAIN返回SELECT语句中使用的每个表的一行信息。它按照MySQL在处理语句时读取表的顺序列出了输出中的表。MySQL使用嵌套循环连接方法解析所有连接。…

探索未来,开启无限可能:打造智慧应用,亚马逊云科技大语言模型助您一臂之力

文章目录 什么是大模型&#xff1f;大模型训练方法亚马逊云科技推出生成式AI新工具 —— aws toolkit使用教程 总结 什么是大模型&#xff1f; 近期&#xff0c;生成式大模型是人工智能领域的研究热点。这些生成式大模型&#xff0c;诸如文心一言、文心一格、ChatGPT、Stable …

JMeter实现持续压测websocket

1、安装插件&#xff1a;JMeter WebSocket Samplers pjtr / JMeter WebSocket Samplers / Downloads — Bitbuckethttps://bitbucket.org/pjtr/jmeter-websocket-samplers/downloads/ 将下载的Jar包放在安装jmeter的/lib/ext路径下&#xff0c;重启生效 查看测试计划--》配置…

LeetCode(6)轮转数组【数组/字符串】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 189. 轮转数组 1.题目 给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例 1: 输入: nums [1,2,3,4,5,6,7], k 3 输出: [5,6,7,1,2,3,4] 解释: 向右轮转 1 步: [7,1…

使用LLama和ChatGPT为多聊天后端构建微服务

微服务架构便于创建边界明确定义的灵活独立服务。这种可扩展的方法使开发人员能够在不影响整个应用程序的情况下单独维护和完善服务。然而&#xff0c;若要充分发挥微服务架构的潜力、特别是针对基于人工智能的聊天应用程序&#xff0c;需要与最新的大语言模型&#xff08;LLM&…