Introspector
一位维基教科书用户认为此页面应该拆分为较小的页面,包含更窄的子主题。 您可以通过将此大型页面拆分为较小的页面来提供帮助。请确保遵循命名策略。将书籍分成更小的部分可以提供更多的关注点,并允许每个部分都能很好地完成一件事,这将使每个人受益。 |
一位读者要求改进此书籍的格式和布局。 良好的格式使书籍更容易阅读,对读者更有吸引力。有关想法,请参阅编辑维基文本,有关优秀书籍的示例,请参阅WB:FB。 即使此消息已删除,也请继续编辑此书籍并改进格式。有关当前进度,请参阅讨论页面。 |
这是解释 Introspector 项目的一系列视频记录中的第一个。
我决定,简单地自我介绍是解释项目背景和目的的最佳方式。
这些视频将托管在 wikibooks.org/wiki/Introspector 上,但也发布到 Youtube 和其他门户网站上。
这个视频应该能让我的朋友和家人理解,也能让其他程序员感兴趣。
内容将分成模块,这样人们就可以跳过不感兴趣的材料。
我们将介绍 Introspector 项目的许多方面,并为学习一般计算奠定基础。
我将解释什么是编译器,什么是编程语言,并尝试包含计算机的基础知识以介绍计算。
简而言之,编译器将人类编写和可读的指令翻译成控制计算机的机器指令。
gcc 编译器翻译了 5 种不同的语言,包括 C、C++、Java、Fortran、Pascal 和 ADA,并将它们翻译成基于 Windows 的英特尔机器、基于 Linux 的英特尔机器、运行在摩托罗拉处理器的旧款 Macintosh 机器以及地球上基本上所有的硬件的机器语言。
稍后,我们将从 gnu g++ 编译器扩展到 gnu 工具,如 gnu bash shell 和 Linux 操作系统内核。
bash shell 将被介绍为一个编译的 C 程序,然后是您使用的程序。
我们将介绍 bash 编程的基础知识,因为它有自己的语言,并展示 bash 函数如何由 C 程序解释和执行。
我们将展示 bash 如何使用 C 运行时库函数来调用操作系统函数并控制硬件。
我们将创建基本程序,然后向您展示从编写源代码到编译、链接、运行和调试代码的所有步骤。我希望能够让人们感受到将计算机程序翻译成运行系统所涉及的所有步骤。
一个视频将向您展示如何在 cygwin windows 上安装 gcc 编译器,并自行编译其中的更改。
其他视频将向您展示如何应用补丁,如何调试编译器以及哪些类型的补丁可用。
其他视频将展示编译器中可用的各种调试选项和转储文件。
我们将回顾编译器的一些模块,解释提供的函数、编写它们的人以及它们的使用方法。
我们将逐步讲解课程,解释从编译器提取数据的必要性,以及对 Introspector 需求的动机。
然后我们将进入 RDF 和语义网,作为编译器图的智能表示。
稍后我们将介绍像 graphviz 这样的可视化工具以及图表的处理方法。
感谢您的收听,期待您的反馈。
内省本质上是计算机世界中更为人知的反射。术语“intro”让我们联想到内部,向内部看,而不是反射,反射意味着镜子。对我来说,内省意味着查看程序的结构。这意味着查看私有和内部数据,并赋予这些数据意义,因为我们知道它(在那一刻)。考虑到所有参与程序和计算机系统各个部分创建的人员,如果没有访问所有人的知识,我们就无法实现完全的内省。这意味着内省会有局限性,但我们可以通过获得足够多的有关代码的数据集来破解它。
因此,内省是一种手段,当正确应用时,可以帮助破解软件代码,并截取程序内部隐藏和封装的含义。
内省是一种方式、一种方法或过程,通过将数据收集器注入到拥有有关您的软件的最多信息的程序中,并以一种可理解的形式收集这些信息,来打破数据隐藏和封装的约定。
数据收集器的注入涉及修改现有程序,或者通过调试器修改执行路径。
如果只有二进制可执行文件,则可以应用此技术,因为我们可以对操作系统、shell 和动态链接器和加载器进行内省。我们可以对汇编处理工具进行内省并添加信息。我们可以通过了解处理器来对执行进行内省,以进行分析。
如果无法访问操作系统,也无法访问工具链,则几乎不可能在机器级别上应用内省。内省过程可以应用于人工操作员、控制台和屏幕截图,所有交互、所有输入和输出都被收集到系统中和从系统中收集。
整个想法是,收集到的这些数据可以与其他系统在外部收集的其他数据进行交叉引用。交叉引用是理解和丰富数据的关键,这是信息获取和丰富过程。
完整的内省过程需要信息才能发挥作用。
我们只关注免费/开源软件,因为它是我们拥有足够公开信息来处理的唯一软件。
让我们从定义 GNU Linux 操作系统是如何设置的开始。
使用测试用例,我们可以记录函数的输入和预期输出。通过汇编和数据流分析,我们可以了解数据上发生的各种操作类型。我们可以跟踪变量的使用位置和方式。通过源代码,我们可以自动解码二进制文件。通过变更控制日志,我们可以自动记录源代码。通过邮件列表,我们可以理解有关源代码变更的讨论。如果给定一个 SourceForge 票证系统,我们也可以以一致的方式构建这些工件。现在,所有这些方面都为程序添加了信息。但是,当我们了解有关编译器如何处理源代码的所有信息时,我们也可以自动将所有这些信息连接在一起。
Bash 是一种 shell,它也是一个程序。shell 与操作系统(核心)交互。shell 保护用户免受核心内部的干扰。strace 可以帮助拦截对操作系统的调用。对操作系统的调用可以看作是从 shell 到核心再回来的线路。了解操作系统的使用情况及其资源(如内存和文件系统)对于理解程序至关重要。操作系统的使用情况无法直接查看。shell 的实现也是隐藏的。
完全理解与抽象理解:所有这些隐藏的数据都是为了完全理解所需的。然而,可以通过坚持使用接口来获得抽象理解。我们可以构建一个处理的抽象模型。根据收集数据的深度,我们可以获得更详细的理解。处理器内部很难访问。每个处理器都不同。公司竭尽全力保护芯片设计并将其保留给自己。这给了他们优势。
我们可以假设,每个可用的工具都需要有其存在的目的,才能生存。工具的生存能力是可以思考和分析的。降低其他工具保护级别的工具可以被视为降低访问成本。然而,这些工具本身也存在成本。我们可以用另一组较低的障碍取代一组较高的障碍,但障碍仍然存在。
问题必须被简化,这需要决策。第一步涉及人类模式匹配。这也可以被编码,但仍然存在成本。人们还需要消耗资源才能生存,因此不客观。我认为,一个社会方面是,人们会保护自己的利益,以避免做任何会威胁其环境稳定的事情。学习某件事的成本是他们希望获得回报的。如果生产或学习工具的成本很高,那么就会人为地制造障碍,以确保其他人无法轻松地访问它。这是信息保护的关键问题之一。生产者收集的资源越多,他们用来保护自己的资源就越多。当一个系统崩溃成自身并开始保护自己作为生存系统时,将会出现一个临界点。
技术中存在着如此之多的问题,这一事实本身就意味着只有那些得到支持的问题才能生存。为了获得支持,它们需要有一个明确的生存能力模型。
程序实际上是一组汇编指令,也可以分析每条指令都以一串字节编码。我们可以分析每个字节的信息并获取有关它的信息。
然而,为了理解这些信息,我们需要将它们与从其他系统获得的信息联系起来。这需要在许多不同的系统之间进行通信。通信很困难,因为它们之间通常有许多不同的障碍。
通过分析机器,我们能够看到执行路径如何将它们连接起来。然而,为了做到这一点,我们需要有一组可以理解的测试。理解测试可能只意味着我们可以将测试用例映射到我们也理解的规范上。规范将被分成人类可以理解的部分。规范的语言也可以由语言工具解析,这将为我们提供一个包含标识符的图结构,这些标识符可以映射到测试中找到的东西。
因此,理解可以定义为将关于测试执行获得的数据图完全映射到从规范中提取的数据图。
我们首先定义一种方法来描述相互连接的图层。每一层将从不同的工具中提取。然而,每一层都将用一种通用语言描述。RFD 的图。
层本身就是一个程序,可能的图类型总数非常大。这意味着测试用例将代表所有可能的图数据的一小部分。重点是这些图之间的连接和映射。
程序也不总是有效地工作,因此可能存在大量实际上不需要解决测试用例本身的处理。假设一个配置文件会标记真正执行的处理路径。
给定一个大型测试用例,我们可以然后寻找与较大测试用例匹配的小型测试用例的重叠部分。这将使我们能够将大型图分解成更小的子图。
然后,我们还可以断言所有这些工作都是为了特定目的而完成的。这个目的是被理解的,它限制了问题的范围。我们需要理解这个范围,以防止浪费资源。
我们可以通过理解人类解决问题所需的努力来迭代地定义系统。我们需要为他们提供有效工作的工具。
binutils 允许我们处理二进制程序,源代码和二进制文件之间存在关系,它是通过编译器创建的。理解程序的源代码可以理解编译器处理的程序。编译器由 shell 运行。在调试器中设置断点允许在调试或检查程序时检查变量。你很容易被信息淹没。可以使用附加到断点的脚本将信息收集到文件或流中。工具可以用于处理收集的信息以使其有意义。我们经常需要显示从依赖项中收集的图以理解它。图结构对于人类来说很自然,RFD 基于图。
最初的动机
[edit | edit source]作者 James Michael DuPont 描述了他对该程序的最初动机
最初的想法来自我对逻辑编程和程序生成器的研究。我曾试图在青少年时期学习 Turbo Prolog,但从未完全掌握它。然而,我喜欢阅读编程手册,并且做了一些示例程序。对我来说,问题是我没有从逻辑上理解其含义的概念,而更像是把任天堂游戏塞进插槽的孩子。数据库断言是让我感到困惑的部分,我不明白这些语句本身也是对象。
从拥有所有图形界面的 DBASE V 开始,我很快就能熟练地创建数据库。然后我也做了一些 DBASE III 的工作。早在 80 年代后期,RAD 就流行起来。FoxPro、Paradox 以及 Alpha4 和 Zachary 等其他环境对我来说至关重要。
RAD 交互式程序生成器和编辑器使用结构化的数据模型,允许程序员快速解决程序。有意义的导入和导出功能,再加上远程网络文件访问和锁定,是你创建交互式人员工作组所需的全部功能。
这些是我在设计该程序时脑海中所设想的概念的原始模型。这是在查看 Introspector 项目时要牢记的模型。我使用这些工具为我家人中的商界人士解决问题。
在设计该程序时,我最初对程序实现的理解有限,并且专注于实际问题解决,这一点应该牢记。
现在,当我们编写文档时,很难识别所有从程序员思维中流入文档的数据流。
然而,我们应该认为,我们有可能意识到我们当前的处境,并希望摆脱单调的处境。将心理流压缩成更紧凑的形式并执行写入操作是一个原子任务。我们可以将数据流视为随着时间推移而倒塌的纸牌屋。然后,将符号写入键盘上的输出是最终的行动提交。然后,我们可以在另一个阶段将该符号作为输入读回来。将纸牌屋重新搭建在一起需要的不仅仅是纸牌,这就是模型需求显而易见的地方。模型基本上是你解码消息所需的所有数据。对于计算机来说,这就是它执行一条字节指令的时刻。因此,该指令的模型将是能够将其追溯到系统中某个时间点的某个外部模型所需的所有数据。
从这种模型中生成的程序将在文件名、变量名、函数名,甚至在文字常量、注释以及其他各种用户数据部分中包含对其生成模型的回溯引用。给定这样的用户空间模型,我们可以为每个程序声明赋予一个含义。含义是在应用程序模型中定义的。
Introspector 的目的不是在任何时候为所有人提供所有数据,而是按需提供有关软件程序的结构化数据,以帮助你快速解决问题。想法是,你必须从你只能部分访问的系统中获取信息;使用自省过程,你可以通过创建拦截器对象来提取来自处理程序的工具的数据,这些拦截器对象可以挂钩到正在运行的进程并捕获任何进出程序中的某个点的數據。
程序的执行点可以定义为程序的指令指针。给定一个测试特定功能的测试用例,我们将能够将给定的输入文件映射到模型位置。
我们可以将此 wiki 视为规范。wiki 页面每个版本都可以视为一种资源。该版本的每个词都可以用作索引。使用这种索引模式,我们可以用维基百科定义程序的所有部分。
假设有一个程序的实现,它由某个文档指定。这在某个主机上的某个进程中执行。
我们可以通过其偏移量来定义输入数据中的一个点。这是对模型的引用。只需要一个寄存器来引用存储在数组中的模型。
只有通过选择和定义一个正式的观点,你才能从编译器获得的数据洪流中得到任何意义。
它的引导想法是使用 GCC 的一个版本,该版本使用内置树转储程序的修改版本,将关于 AST 的打印语句转换为 wikipedia:资源描述框架 格式中的实时数据,通过 wikipedia:Redland API。
以下是一些关于 gcc 接口 Introspector/GccCpp 的信息。
已经进行并存在各种实验,使用针对编译器图优化的底层后端表示,以及使用特殊 wikipedia:数据结构 “冰块” 进行更高速度的数据传输的实验。冰块是压缩数据立方体,是一组有效地描述编译器图的向量。
数据直接编译到程序中,因此数据在程序启动时加载。这不允许更改数据。那是 2003 年。
后来,在 2005 年 1 月,我使用 C 创建了更紧凑的图形表示,以及使用它们的算法。这是一个好的开始。它将图形存储为固定长度的记录,可以从文件系统中以块的形式加载。
目标
对于本地使用:最终目标将能够在需要时生成一个共享对象,该对象将为在该机器上加载生成图形的最紧凑和最快的表示。我们还可以使用核心转储,因为图形数据存储在中性格式中。
对于传输:如果你想导出一个图形,那么将它存储为 RDF/XML 将是最佳选择。
已经构建了 Postgres 接口,存储收集的图形。第一个版本的数据库结构直接基于节点类型。每个节点类型一个表。
此外,我使用 redland 创建了数据库,它创建表以直接表示图形。
使用数据库表的问题是,你需要有以下约束
局部性:在编译器中一起出现的记录应该以一种可以一起检索的方式存储。
记录类型:记录的类型及其拥有的字段需要仔细选择。记录类型非常多。例如,函数声明的类型非常多。
对数据库表使用联合类型并不总是明智的,将所有实例存储在同一个表中。
第一个自省样本是从 gcc wikipedia:抽象语义图 收集的。
所有这些工具都处于分离状态,尚未集成。
我们要做的是了解系统的各个层。
- Introspector/Compiler/Input Stream
- Introspector/Compiler/Lexical Tokens
- Introspector/Compiler/Parse Tree
- Introspector/Compiler/AST
- Introspector/Compiler/RTl
- Introspector/Compiler/Dwarf
- Introspector/Linker/Elf/Section
- Introspector/Linker/Elf/Label
- Introspector/RDF
- 将 printfs 转换为 rdf 发射的 API
- 每个 PrintF 的调用栈
- 分析表达式中每个变量的数据流
- Introspector/Graph Layout
- Introspector/Annotation
Introspector/Project 的目标是构建 Introspector/Project/Goals,为 WG:Free_Software_and_Open_Source_software 和 Introspector/SourceCode 构建 Introspector/MetaData/Manipulation/Tools。
Introspector 是一种新的 Introspector/ToolChain,用于从 GnuCompilerCollection 和其他 FreeSoftware LanguageTools(如 PerlLanguage、CSharpLanguage、BashLanguage)中提取关于你的软件程序的 Introspector/MetaData,并将其呈现给你,使你作为程序员的工作更轻松。使用可扩展样式表之类的转换,代码元编程将变得轻而易举。正在开发将软件信息压缩成图形和 GUI 的代理。
该软件是按照 GnuManifesto 的精神开发的自由软件,它在赋予用户自由方面具有革命性意义。
这些元数据包括编译器、make & build 系统、savannah/sourceforge 项目管理和 debian 打包系统、CVS 更改以及 mailman 邮件列表软件收集的有关你的软件的所有数据。
Introspector 的范围最初只是 GCC C 编译器,但现在已扩展到包括从不同编译器和解释器(如 Perl、bison、m4、bash、C#、Java、C++、Fortran、objective-c、Lisp 和 Scheme)中提取元数据。将正式提交各种补丁,以允许 Introspector 以标准形式提取数据。
这些提取的元数据存储在 ntriple rdf 文件中,一个按程序运行、输入文件、声明的函数或类以及自省的时间和日期分类的存储库。这些文件是标准化的,可以通过 Redland RDF API 供 eulersharp、cwm、Java、Perl、C、C++ 等工具访问。这些 rdf 文件可以通过 redland 存储接口并发访问。
元数据将从以下免费工具中提取
- GCC 编译器的抽象语法树
- DotGNU/PNET/CSCC 和 DotGNU/PNET/Ccompiler 的抽象语法树
- PerlInternals 接口
- Bash Shell 将扩展到也将其对象转储到 Rdf 中(基于 BashDB)
- BisonParseTree 以及 BisonRules BisonTokens
- M4MacroLanguage
- Debian-SF sourceforge 应用程序存储库 GForge
- PhpLanguage
- PythonLanguage
- SilverSchemeLanguage
我们正在为 FreeSoftware 构建 IntrospectorInterfaces,以允许各种应用程序处理这些元数据。
include
- 数据提取工具
- 数据表示
- 数据仓库
- 数据可视化工具
- 代码生成工具
包含以下接口
- Emacs 接口
- Bash 接口
- Dia 接口
includes
- Vcg 接口
- AutoDia 接口
- Dia 接口支持。
supports
- N3、RdfFormat、EulerSharp、CWM、RedlandInterface、NtriplesFormat、PerlRdfLaces
- XmlFormat
- HtmlFormat
- 表格文本文件格式
Introspector 本体工作已经准备好集成。
我已经创建了描述 gcc 编译器节点的本体的更新版本。
以下是本体的各个方面
1. 在 tree.def 中定义的节点 2. 在 c、tree.h 中定义的数据结构 3. 在 tree-dumper.c 中转储的数据结构 4. 宏中定义的数据结构访问方法 5. gcc 自身代码中树的使用。
树的哪些方面用于构建编译器本身。
- 树的哪些方面用于定义树。
- 树的哪些方面用于填充树。
需要什么测试代码来运行编译器并执行所有代码路径?需要哪些路径来填充树的所有方面?树的哪些部分来自用户数据?树的哪些部分来自编译器数据?
编译器本身内置了什么数据?编译器版本之间有什么区别?
标准头文件创建了什么数据?使用了哪些版本的头文件?
1. 从运行编译器创建了哪些类型的记录?
我们想了解从编译器收集的真实数据的类型。我们希望看到每个出现的输出数据配置的本体类型记录。
理想情况下,我们将数据类型定义为通过编译器的完整执行路径,影响数据的每条指令都将记录在类型历史记录中。
目前,我们收集出现的数据类型并为每个类型创建一个类型。这就是我所说的实例类型。
2. 每种数据类型都有哪些公共字段
对于每种数据类型,每个字段集都有一组子集,这些子集也出现在其他记录中。我们计算字段的最大公集并将其与实例类型相关联。
警告: 在 OWL 中,定义了超集/子集关系,其中实例类型是更一般类型的超类型。为什么
3. 哪些字段是仅对数据排序的列表字段?
4. 哪些字段代表程序的含义? 5. 哪些其他类型的记录被字段引用? 6. 通过哪些字段哪些其他记录引用了什么类型的对象?
我的目标是使用内置在 gcc 中的 fact++ 推理器,在一个进程中执行。
为了实现这一点,我们需要处理以下问题:
1. 何时向推理器提供数据
我们可以向推理器提供数据:
- 对于第一步,我们可以处理 gcc 的转储函数。
- 在编译器中首次收集数据时。
- 在编译完成后。
- 当用户定义的代码被执行时触发。
- 当在编译外部的 RDF 中定义的用户定义模式出现在代码中并被匹配时
- 我们希望能够在常量折叠阶段处理数据
2. 向推理器提供哪些数据
我们可以根据以下内容创建记录:
- 编译器本身的数据结构。
- 数据转储函数,基于记录类型。
- 用户定义的代码,使用属性标记需要哪些数据
- 使用 RDF 来描述要收集哪些数据
3. 如何处理推理器的结果
- 我们需要能够将多次编译运行的结果合并在一起
- 我们希望能够影响编译本身。创建新结构。
- 我们希望能够定义在编译期间执行的用户代码(常量折叠表达式),这些代码基于
从编译器收集的常量数据。
- 我们希望生成新的代码,这些代码会被编译和链接
需要能够
- ExtractWiki
- ExtractMbox
- ExtractSavannah
- ExtractCvs
数据仓库需要一个用户管理和声明管理系统。
以下是 IntrospectedProjects 的示例。
另请参阅:相关项目 相似名称项目 已使用项目 受影响项目 客人日志
以下是要编辑的章节
- Introspector/DotGNU/RDF
- Introspector/Interfaces/CVS
- Introspector/Interfaces/CoopX
- Introspector/Interfaces/Foaf
- Introspector/Interfaces/GUI
- Introspector/Interfaces/MBOX
- Introspector/Interfaces/Projects/Savannah
- Introspector/Interfaces/Projects/VCG
- Introspector/Interfaces/Wiki/OddMuse
- Introspector/Introspection
- Introspector/LanguageTools/Bash
- Introspector/LanguageTools/Perl
- Introspector/LanguageTools/Php
- Introspector/LanguageTools/Python
- Introspector/LanguageTools/SilverScheme
- Introspector/RDF/Laces
- Introspector/RDF/Swoogle
- Introspector/RelatedProjects/SimilarNamed
- Introspector/Snippets
- Introspector/gcc/rtl/peephole/i386.md
- Introspector/RTL in Lisp
,例如:我们将首先分析一个相关的 c 文件
当我们查看以下链接时
http://introspector.sourceforge.net/2005/07/bary/doxygen/html/structgnode.html
这张图片很好地概述了 gnode
http://introspector.sourceforge.net/2005/07/bary/doxygen/html/structdllist__coll__graph.png
以下是从 DWARF 数据中获取的另一个示例
http://en.wikipedia.org/wiki/DOAP https://wikibooks.cn/wiki/Reverse_Engineering http://en.wikipedia.org/wiki/Core_dump http://en.wikipedia.org/wiki/Introspector_%28program%29
另请参阅:AspectX、srcML、XWeaver
- Binge
- carl - 代码分析和重构库
- CPPX
- GccXML 非常相似
- GaSta 基本上是同一个项目
- llvm
- ProgramTransformation
- Stratego
- Synopsis
- MetaCPP