【go编译和反编译概述】

go是和c语言一样的静态语言,因此也就存在着编译的过程。然后反编译其实是为了看系统的整个调用。

编译

编译主要是通过go build 这个命令去做的。通常的go run main.go其实也是在编译完成之后,直接运行代码里面的main方法。
然后也可以通过,go build 方法,先变成成为可执行文件之后再进行运行,加上-o指定可执行文件需要进行存放的目录。
当然go build 也有很多可以选择的参数,可以在安装完go之后,通过go help build进行查看。
用的比较多的参数有

-a

-a 强制编译,即使是代码没有进行更新,其实就是和makefile有点类似,本身make之后会有缓存,如果代码没有更新,make的时候会提醒.-a 就是即使没有更新也要重新编译。

-p

-p n.这个是后面接上参数的,一般是cpu的数量,缺省是设置的GOMAXPROCS.这个也是go编译这么快的原因之一,可以并发编译。

-race

-race 开启竞态检测,其实也就是检测有没有并发的问题。
接下来我们用一个示例代码,下面的代码明显是有着并发的问题。然后看看不加-race和加了的区别

package main

import (
	"fmt"
)

func main() {
	var a int

	a = 1

	go func() {
		a++
	}()

	go func() {
		a++
	}()

	fmt.Printf("is int:%v\n", a)

}

不加-race
在这里插入图片描述

加了race
在这里插入图片描述

因为截屏显示的问题,把内容都复制出来。

==================
WARNING: DATA RACE
Read at 0x00c0000b8018 by main goroutine:
  main.main()
      /Users/wangjian01/Documents/go/learn/study/runtime/map/t1.go:20 +0x134

Previous write at 0x00c0000b8018 by goroutine 7:
  main.main.func1()
      /Users/wangjian01/Documents/go/learn/study/runtime/map/t1.go:13 +0x44

Goroutine 7 (finished) created at:
  main.main()
      /Users/wangjian01/Documents/go/learn/study/runtime/map/t1.go:12 +0xbd
==================
is int:3
Found 1 data race(s)

很明显看这个不同的goroutine的读写操作说明的很清楚,因此需要根据提示做出加锁或者进行原子等操作避免。

我们试一下正确的代码下的输出。这个是加了读写锁的代码。

package main

import (
	"fmt"
	"sync"
)

func main() {
	var a int

	a = 1
	var lock sync.RWMutex

	go func() {
		lock.Lock()
		a++
		lock.Unlock()
	}()

	go func() {
		lock.Lock()
		a++
		lock.Unlock()
	}()

	lock.RLock()
	fmt.Printf("is int:%v\n", a)
	lock.RUnlock()

}

再加上-race进行编译,看已经没问题了
在这里插入图片描述

gcflags

go build 可以用-gcflags给go编译器传入参数,也就是传给go tool compile的参数,因此可以用go tool compile --help查看所有可用的参数。
在这里插入图片描述

其中-m可以检查代码的编译优化情况,包括逃逸情况和函数是否内联。

如果只在编译特定包时需要传递参数,格式应遵守“包名=参数列表”,如go build -gcflags -gcflags=‘log=-N -l’ main.go

go build用-ldflags给go链接器传入参数,实际是给go tool link的参数,可以用go tool link --help查看可用的参数。

常用-X来指定版本号等编译时才决定的参数值。例如代码中定义var buildVer string,然后在编译时用go build -ldflags “-X main.buildVer=1.0” … 来赋值。注意-X只能给string类型变量赋值。

通常为了调试的参数是-N参数代表禁止优化, -l参数代表禁止内联,

反编译

主要是为了底层如何运行,而将二进制文件转换成了汇编文件。

方法一

先编译成二进制,然后通过二进制文件,反编译成汇编文件。以上面的为例,

go build -o main
go tool objdump -S main > plan9.asm

然后看一下结果,因为比较多这里只截图一部分,
在这里插入图片描述
忽略其中的汇编,可以看到对于lock.RLock()的底层调用,对于我们的分析底层还是很有帮助的。

方法二

   go tool compile -S -+ -l -m t1.go > plan9.asm

通过compile这个工具,可以看出编译器的整个过程,上面的是-m生成的效果,编译器的优化。
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
NET程序员的开发利器.NET Reflector 一、 简介   程序集,作为.NET时代的动态链接库,蕴藏了太多的软件秘密。为此,Visual Studio内置的ILDASM成为最初挖掘程序集的上佳工具。但自从Reflector出现后,ILDASM相形见拙。因为,Reflector能提供更多的程序集信息,而且是免费的工具。   如今,在Visual Studio.NET中编译源代码(无论是VB还是C#)时,编译器都会将高级源代码翻译成MSIL,即“微软中间语言”,而不是特定的机器指令。具有更多安全性、版本控制、共享能力与其它相关元数据的中间语言(IL),是包在一个或多个DLL或可执行文件中的。   基于ILDASM检查程序集中的IL有时很有用,但它要求我们熟悉MSIL。通常,比起IL,大多数开发人员对像C#或Visual Basic这样的高级程序设计语言更为熟悉。   Reflector的出现使.NET程序员眼前豁然开朗,因为这个免费工具可以将.NET程序集中的中间语言反编译成C#或者Visual Basic代码。除了能将IL转换为C#或Visual Basic以外,Reflector还能够提供程序集中类及其成员的概要信息、提供查看程序集中IL的能力以及提供对第三方插件的支持。   二、 下载与运行Reflector   Reflector是由微软员工Lutz Roeder编写的免费程序。这个软件经常更新,你可以在http://www.aisto.com/roeder/dotnet下载最新的版本。在本文成文之时,Reflector的最新版本为5.0.35.0,仅有1M大小。只要双击下载后的Reflector.exe文件即可运行Reflector。   默认情况下,Reflector会打开一组公共程序集(mscorlib、System、System.Data、System.Drawing等等)。每个打开的程序集都列在Reflector的主窗口中。单击程序集旁边的+图标可以展开树结构并展示程序集的命名空间。每个命名空间旁边都有一个相关的+图标,单击这个图标将显示这个命名空间内的类。除此以外,还可以展开每个类,显示类的成员:事件、字段、方法与属性。   要想查看其它程序集(包括我们自己创建的程序集)的细节,你可以使用菜单命令“File→Open”。然后,浏览到想要查看的程序集。只要选择了有效的.NET程序集,这个程序集就可以在Reflector的主窗口中与其它默认程序集共同显示。要想从Reflector的主窗口中删除程序集,只需右击程序集并选择“Close”。   三、 使用Reflector反汇编程序集   提供基本的程序集是Reflector唾手可得的功能,然而,Reflector真正的威力体现在它的反汇编能力。只要浏览到类级的成员,就可以通过Tools菜单中的Disassembler项(或在该项上单击右键)反汇编此成员。这将打开第二个窗格,以C#、Visual Basic、Delphi或者IL显示反汇编后的内容。图2以C#语言展示了对SmtpClient类中Abort方法的反汇编结果。   有了Reflector的反编译功能,要研究.NET框架基类库就容易多了。我们完全可以在没有源代码的情况下研究我们所创建或者正在使用的程序集相应源代码。   不用太担心,你自己的.NET应用程序还有其它受保护措施。但是,想阻止别人查看.NET程序集的IL(继而反编译成C#或者Visual Basic)是不可能的,但你可以使用“混淆”技术使IL变得混乱。目前,市场上有许多.NET混淆产品,比如:PreEmptive Solution的Dotfuscator、WiseOwl的Dmeanor以及Remotesoft的.NET Obfuscator等。   四、 Reflecator的其它功能   除了作为对象浏览器与反汇编器之外,Reflector还可以显示类与其成员的调用与被调用图、提供单键访问Google或MSDN搜索的能力并提供了允许第三方开发人员为Reflector创建插件的框架。   要查看调用或被调用图,只需要在树视图中选择一个成员,访问Tools菜单,选择Call Graph或Callee Graph选项即可。Call Graph会列出所选项所调用的成员,而Callee Graph列出调用所选项的成员。   通过使用插件,Reflector的功能可以得到进一步扩展。目前有能显示程序集依赖图、自动加载当前运行中的程序集、输出整个程序集的反汇编内容以及在Visual Studio中作为Reflector的宿主等的插件。还有更多插件都列在http://www.codeplex.com/reflectoraddi

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值