首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

如何在Clang中使用llvm ir发出调试信息?

在 Clang 中使用 LLVM IR 发出调试信息可以通过以下步骤实现。调试信息通常包括源代码位置、变量信息、函数信息等,这些信息可以帮助调试器(如 GDB 或 LLDB)在调试时提供更详细的上下文。

1. 编译时启用调试信息

首先,你需要在编译时启用调试信息。你可以使用 -g 选项来生成调试信息。

代码语言:javascript
复制
clang -g -emit-llvm -c your_code.c -o your_code.bc

这将生成包含调试信息的 LLVM 位码文件 your_code.bc

2. 使用 llvm-dis 查看生成的 LLVM IR

你可以使用 llvm-dis 工具将位码文件转换为人类可读的 LLVM IR,以查看生成的调试信息。

代码语言:javascript
复制
llvm-dis your_code.bc -o your_code.ll

打开 your_code.ll 文件,你应该会看到类似以下的调试信息:

代码语言:javascript
复制
; ModuleID = 'your_code.c'
source_filename = "your_code.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4}
!llvm.ident = !{!5}

!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "your_code.c", directory: "/path/to/your/code")
!2 = !{}
!3 = !{i32 2, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{!"clang version 10.0.0"}

3. 手动在 LLVM IR 中插入调试信息

如果你需要手动在 LLVM IR 中插入调试信息,可以使用 llvm.dbg 元数据。以下是一个简单的示例,展示如何在 LLVM IR 中插入调试信息。

代码语言:javascript
复制
; ModuleID = 'example'
source_filename = "example.c"
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@.str = private unnamed_addr constant [13 x i8] c"Hello, world\00", align 1

define i32 @main() !dbg !5 {
entry:
  %0 = alloca i32, align 4
  %1 = alloca i32, align 4
  store i32 0, i32* %0, align 4
  call void @llvm.dbg.declare(metadata i32* %0, metadata !10, metadata !11), !dbg !12
  %2 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([13 x i8], [13 x i8]* @.str, i32 0, i32 0)), !dbg !13
  store i32 %2, i32* %1, align 4
  call void @llvm.dbg.declare(metadata i32* %1, metadata !14, metadata !11), !dbg !15
  %3 = load i32, i32* %1, align 4, !dbg !16
  ret i32 %3, !dbg !17
}

declare i32 @printf(i8*, ...) #1

!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!3, !4}
!llvm.ident = !{!5}

!0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2)
!1 = !DIFile(filename: "example.c", directory: "/path/to/your/code")
!2 = !{}
!3 = !{i32 2, !"Dwarf Version", i32 4}
!4 = !{i32 2, !"Debug Info Version", i32 3}
!5 = !{!"clang version 10.0.0"}
!10 = !DILocalVariable(name: "retval", scope: !6, file: !1, line: 1, type: !7)
!11 = !DIExpression()
!12 = !DILocation(line: 1, column: 1, scope: !6)
!13 = !DILocation(line: 2, column: 1, scope: !6)
!14 = !DILocalVariable(name: "result", scope: !6, file: !1, line: 2, type: !7)
!15 = !DILocation(line: 2, column: 1, scope: !6)
!16 = !DILocation(line: 3, column: 1, scope: !6)
!17 = !DILocation(line: 4, column: 1, scope: !6)
!6 = distinct !DISubprogram(name: "main", linkageName: "main", scope: !1, file: !1, line: 1, type: !8, isLocal: false, isDefinition: true, scopeLine: 1, flags: DIFlagPrototyped, isOptimized: false, unit: !0, variables: !2)
!7 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
!8 = !DISubroutineType(types: !9)
!9 = !{!7}

4. 使用调试器调试生成的代码

生成包含调试信息的可执行文件后,你可以使用调试器(如 GDB 或 LLDB)来调试代码。

代码语言:javascript
复制
# 使用 Clang 生成可执行文件
clang -g your_code.c -o your_executable

# 使用 GDB 调试
gdb your_executable

# 使用 LLDB 调试
lldb your_executable

在调试器中,你可以设置断点、查看变量值、单步执行代码等。

通过这些步骤,你可以在 Clang 中使用 LLVM IR 发出调试信息,并使用调试器调试生成的代码。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

微信安全下一代特征计算引擎的探索与实践

注意Clang前端并不是Clang二进制程序, 而是Clang编译器提供的前端库,LLVM IR经过LLVM优化器,根据优化级别生成优化后的LLVM IR存储在内存, 常见的优化有常量传播,常量折叠,...LLVM将传统的三段式结构优化阶段单独提取出来,并引入了一个通用的代码中间表示LLVM IR,这样前端研发人员只需要关注Source Code到LLVM IR的过程,专注前端的相关的算法 新的parser...信息主要由3部分组成:位置信息factorial.cpp:1:1 文件第1行第1列。...clang -S -emit-llvm factorial.cpp EmitLLVMOnlyAction它的名字含义一样,只输出LLVM IR,FrontendAction还有其他的子类实现,包括EmitAssemblyAction...节点的函数,访问表达式VisitDecl和访问声明VisitDecl,都是可重写的函数: 示例clang-funcnames实现了自定义的MyASTVisitor: 总结下一下,如果使用Clang进行静态代码分析

19610

iOS编译简析

编译器后端(BackEnd): 将得到的中间代码转化为各平台的机器码, x86,ARM 等。 从 GCC 到 LLVM 以及大部分编译器都是这种结构。...iOS 在 Xcode 5 版本前使用的是 GCC ,在 Xcode 5 中将 GCC 彻底抛弃,替换为了 LLVM ,这期间也是慢慢过渡过来的,由开始使用 GCC 编译->GCC 与 LLVM 共存-...如果所示,不同的前端后端使用统一的中间代码 LLVM Intermediate Representation (LLVM IR),如果需要支持一种新的编程语言,那么只需要实现一个新的前端,如果需要支持一种新的硬件设备...AST 所占用的内存是 GCC 的五分之一左右 模块化设计:Clang 采用基于库的模块化设计,易于 IDE 集成及其他用途的重用 诊断信息可读性强:在编译过程Clang 创建并保留了大量详细的元数据...由 Clang Parser 和 Sema 配合完成; 静态分析(Static Analysis):使用它来表示用于分析源代码以便自动发现错误; 中间代码生成(Code Generation):开始

1.3K20

LLVM简介

此后,LLVM成长为伞项目下的一个子项目。其中许多是被广泛用于各种各样的商业生产和开源代码项目以及学术研究LLVM项目源码采用“Apache 2.0许可协议”。...由上图可知,LLVM架构下,不同的前端和后端使用统一的中间代码LLVM InterMediate Representation(LLVM IR) 如果需要支持一门新的编程语言,只需要实现一个新的前端...如果需要支持一款新的硬件设备,只需要实现一个新的后端 优化阶段是一个通用的阶段,他针对的是统一的LLVM IR,不论是支持新的编程语言,还是支持新的硬件设备,都不需要对优化阶段做修改。...诊断信息可读性强:在编译过程Clang 创建并保留了大量详细的元数据 (metadata),有利于调试和错误报告 设计清晰简单,容易理解,易于扩展增强 ClangLLVM关系 ?...Clang、Swift、LLVM的关系如下: ? PS: 广义的LLVM是指整个LLVM项目,包括Clang前端。狭义的LLVM是指LLVM后端。

9.8K11

LLVM的ThinLTO编译优化技术在Postgresql的应用

然而,在GNU编译器集合(GCC)和LLVM实现的LTO,编译器能够转储其中间表示(IR),即GIMPLE字节码或LLVM字节码,以便在最终链接时将组成单个可执行文件的所有不同编译单元作为单个模块进行优化...在编译阶段,clang会生成LLVM字节码而不是目标文件。链接器识别这些字节码文件,并在链接过程调用LLVM来生成构成可执行文件的最终对象。...在实践,这意味着LTO通常需要大量的内存(一次性保存所有IR)并且非常慢。而且,如果通过-g启用了调试信息IR的大小和所需的内存要求会显著增加。...因此,第二阶段和第三阶段之间的区别对用户来说是透明的) 这个过程的关键是在第一阶段发出的摘要。 这些摘要使用位码格式发出,但设计得可以单独加载,而不涉及LLVMContext或任何其他昂贵的构造。...Postgresql中使用thinlto技术生成带有模块摘要的IR PG根目录下的Makefile.golbal.in增加了对LLVM的支持,位置: # Install LLVM bitcode module

15910

iOS编译原理

Clang LLVM是苹果当前使用的编译器: LLVM是一套编译器基础设施项目,为自由软件,以C++写成,包含一系列模块化的编译器组件和工具链,用来开发编译器前端和后端; 基于 LLVM 衍生出了一些强大的子项目...CLang基于LLVM,是一个高度模块化开发的轻量级编译器; CLang主要来自苹果电脑的支持,同时支持C、Objective-C以及C++; CLang用于替代Xcode5版本前使用的GCC,编译速度提高了...3倍: 3.理解iOS的编译器 在iOS开发,通常LLVM被认为是编译器的后端,而Clang是作为编译器的前端; 二者以 IR(中间代码)作为媒介,这样前后端分离,使得前后端可以独立的变化,互不影响...词法分析(Lexical Analysis) 主要功能:通过扫描器,分割识别源代码符号(大小括号、=、字符串); 使用xcrun命令,在终端执行词法分析操作: xcrun clang -fmodules...1.LLVM优化中间代码 中间代码IR进入后端,LLVM会对其进行优化: Optimization Level bitcode 2.生成汇编代码 LLVMIR进行优化后,会针对不同架构生成不同汇编代码

1.6K20

自定义Clang命令,利用LLVM Pass实现对OC函数的静态插桩

result = num + 2; } return result;}为了解决上述问题,接下来介绍如何利用Clang在编译的过程修改对应的IR文件,实现把桩函数插入到指定的函数实现。...编译过程图片这里“插桩”的思路就是利用OC编译过程使用自定义的Pass(这里使用的是transformation pass),来篡改IR文件。...图片LLVM IR 文件的描述LLVM IR (Intermediate Representation)直译过来是“中间表示”,它是连接编译器前端和后端的桥梁,它使得LLVM可以解析多种源语言,并为多个目标机器生成代码...执行结果验证生成IR文件调试效果打开llvm的工程,选择clang的target,设置Clang的运行参数 图片把上述的的路径替换成自己的路径// 指定使用new pass manager,llvm里面有两套写自定...在Xcode应用第一步,指定使用自定义的Clang改Build Setting,在User Define新增设置成自定义Clang的地址,注意路径需要指向llvm工程里的目录,如果想要单独拷贝clang

2.2K191

LLVM编译过程

LLVM的中间代码LLVM IR 的三种格式: 内存的编译中间语言 硬盘上存储的可读中间格式(以 .ll 结尾) 硬盘上存储的二进制中间语言(以 .bc 结尾) 这三种中间格式是完全等价的。...Clang 的主要功能是输出代码对应的抽象语法树( AST ),针对用户发生的编译错误准确地给出建议,并将代码编译成 LLVM IR。...Clang 的特点是编译速度快,模块化,代码简单易懂,诊断信息可读性强,占用内存小以及容易扩展和重用等。...架构 Clang-LLVM架构Clang作为前端生成中间代码IRLLVM优化器进行优化,LLVM机器码生成器生成不同的机器码 再具体一些的话: 5、Xcode的编译过程 具体来说,在Xcode...静态分析(Static Analysis):静态分析会对代码进行错误检查,出现方法被调用但是未定义、定义但是未使用的变量等,以此提高代码质量。

1.9K10

iOS底层原理之LLVM & Clang

1.3.1: iOS的编译器架构 Objective-C/C/C++使用的编译器前端是Clang,Swift是Swift,后端都是LLVM。 二: Clang ClangLLVM项目中的一个子项目。...clang -S -fobjc-arc -emit-llvm main.m (滑动显示更多) 2.4: IR的优化 在上面的IR代码,可以看到,通过一点一点翻译语法树,生成的IR代码,看起来有点蠢,...可以使用命令进行优化: clang -Os -S -fobjc-arc -emit-llvm main.m -o main.ll (滑动显示更多) 优化后的IR代码,简洁明了(优化等级并不是越高越好,...通过下面命令,使用优化后的IR代码生成.bc代码: clang -emit-llvm -c main.ll -o main.bc (滑动显示更多) 3: 后端阶段(生成汇编.s) 后端将接收到的IR结构转化成不同的处理对象...本文主要介绍了下LLVMClang相关的概念、设计思想和编译流程,下篇文章将使用LLVMClang实现一个简单的插件,敬请期待。

1.4K10

初识LLVM&Clang-开发Xcode插件

初识LLVM&Clang-开发Xcode插件 LLVM Xcode现在使用的编译器就是LLVMLLVM比以前使用的GCC编译器速度快好几倍。...LLVM IR 的三种格式: 内存的编译中间语言 硬盘上存储的可读中间格式(以 .ll 结尾) 硬盘上存储的二进制中间语言(以 .bc 结尾) 这三种中间格式完全是等价的。...Clang的主要功能是输出代码对应的抽象语法树( AST ),针对用户发生的编译错误准确地给出建议,并将代码编译成LLVM IR。...语法分析: 验证语法是否正确 生成AST: 将所有节点组成抽象语法树AST 静态分析:分析代码是否存在问题,给出错误信息和修复方案 生成LLVM IR: CodeGen 会负责将语法树自顶向下遍历逐步翻译成...这里只是皮毛的皮毛?。

2.4K20

llvm入门教程-Kaleidoscope前端-9-添加调试信息

(PS:初步翻译文档放在github上了,需要可自取,也欢迎提PR共同完善) Kaleidoscope:添加调试信息 第九章引言 欢迎阅读“使用LLVM实现语言”教程的第9章。...源代码级别调试使用格式化数据来帮助调试器将二进制代码和计算机状态转换回程序员编写的源代码。在LLVM,我们通常使用称为DWARF格式。DWARF是一种表示类型、源代码位置和变量位置的紧凑编码。...由于几个不同的原因,调试信息是一个棘手的问题-主要集中在优化的代码上。首先,优化使得保持源代码位置更加困难。在LLVM IR,我们在指令上保留每个IR级别指令的原始源位置。...提前编译模式 为了只强调将调试信息添加到源语言的各个方面,而不需要担心JIT调试的复杂性,我们将对Kaleidoscope进行一些更改,以支持将前端发出IR编译成可以执行、调试和查看结果的简单独立程序...通过DIBuilder发出调试信息的最后一件事是,我们需要“确定”调试信息

70140

微信团队分享:极致优化,iOS版微信编译速度3倍提升的实践总结

LLVM 实现了更通用的编译框架,它提供了一系列模块化的编译器组件和工具链。首先它定义了一种 LLVM IR(Intermediate Representation,中间表达码)。...Frontend 把原始语言转换成 LLVM IRLLVM Optimizer 优化 LLVM IR;Backend 把 LLVM IR 转换为目标平台的机器语言。...中间代码生成(Code Generation):将语法树自顶向下遍历逐步翻译成 LLVM IR。...3)生成汇编代码: LLVMLLVM IR 生成当前平台的汇编代码,期间 LLVM 根据编译设置的优化级别 Optimization Level 做对应的优化(Optimize),例如 Debug...实际上源文件不需要使用某些头文件里的定义( class、function),所以编译时间才那么长。

2.4K43

Julia机器学习核心编程.2(LLVM和JIT)

• 创建LLVM的核心库提供了现代的源和目标的独立优化,并且支持许多流行CPU的代码生成,这些库是围绕LLVM中间表示(LLVM IR)构建的。...• Clang是一个LLVM原生的C/C++/Objective-C编译器,旨在提供惊人的编译速度(例如,在调试编译Objective-C代码时比GCC快3倍),可以提供非常有用的错误警告,并且为构建优秀的源代码工具提供一个良好的平台...• LLDB项目以LLVMClang提供的库为基础,提供了一个出色的本地调试器。...它具有Clang AST和表达式解析器、LLVM JIT、LLVM反汇编器等诸多功能,因此提供了出色的使用体验,并且在加载符号时相比GDB也要快得多,且内存效率更高。...在计算,Julia使用JIT编译(也被称为动态翻译),编译执行在程序运行时,而不是在程序运行前。

87710

Postgresql JIT README翻译

选择 LLVM 是因为它由几个大型公司开发,因此不太可能停止开发,因为它的许可证与 PostgreSQL 兼容,并且可以使用 Clang 编译器将其 IR 从 C 生成。...*context); 然后可以使用 LLVM API 发出尽可能多的代码。...例如,在表达式评估的情况下,这个设置允许在 ExecInitNode() 中发出查询的大多数函数,将函数的发出延迟到第一次实际使用函数的时候。...使用相对较小的进入/离开保护代码部分,而不是全局设置这些处理程序,可以避免与可能使用C++的扩展(PostGIS)产生负面互动。...相反,我们利用Clang编译器可以生成LLVM IR的事实。 这样做的能力使我们能够获取所有操作符的LLVM IR(例如int8eq,float8pl等),而无需维护两个副本。

28920

教程 | 编译器入门:没有siri的那些年,我们如何实现人机对话?

LLVM 是一个广泛使用的编译器项目,包括多个模块化的编译器工具。 传统的编译器设计包括三个部分: ? 前端将源代码转换成一种中间表示(IR)。...clang (http://clang.llvm.org/) 是 LLVM 项目中 C 类语言的前端工具。 优化器解析 IR 并将其转换成一种更高效的形式。opt是 LLVM 项目的优化器工具。...后端通过将 IR 映射到目标硬件指令集上来生成机器代码。llc 是 LLVM 项目的后端工具。 LLVM IR 是一种类似汇编的低级语言。但是,它不针对特定的硬件信息编程。...在 compile_me.c 上运行 clang 前端,生成 LLVM IRclang -S -emit-llvm -o llvm_ir.ll compile_me.c llvm_ir.ll 的...优化器的输入为 IR,输出为优化后的 IRLLVM 的优化器工具 opt 将使用 -O2(大写字母 o,数字 2)标记优化处理器速度,使用-Os(大写字母 o,s)标记优化生成目标的大小。

1.1K60
领券