前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Golang源码分析 | 程序引导过程

Golang源码分析 | 程序引导过程

作者头像
windealli
发布于 2023-10-13 03:33:54
发布于 2023-10-13 03:33:54
26200
代码可运行
举报
文章被收录于专栏:windealliwindealli
运行总次数:0
代码可运行

环境说明

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CentOS Linux release 7.2 (Final)
go version go1.16.3 linux/amd64
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-80.el7

使用gdb查看程序入口

编写一个简单的go程序

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// main.go
package main

func main() {
        print("Hello world")
}
编译
  go build -gcflags "-N -l" -o simple main.go
使用gdb查看entry
gdb simple
(gdb) info files
Symbols from "/data/project/windeal/golang/simple/simple".
Local exec file:
        `/data/project/windeal/golang/simple/simple', file type elf64-x86-64.
        Entry point: 0x45cd80
        0x0000000000401000 - 0x000000000045ecb6 is .text
        0x000000000045f000 - 0x000000000048bdb5 is .rodata
        0x000000000048bf40 - 0x000000000048c3e0 is .typelink
        0x000000000048c3e0 - 0x000000000048c3e8 is .itablink
        0x000000000048c3e8 - 0x000000000048c3e8 is .gosymtab
        0x000000000048c400 - 0x00000000004c7b68 is .gopclntab
        0x00000000004c8000 - 0x00000000004c8020 is .go.buildinfo
        0x00000000004c8020 - 0x00000000004c9240 is .noptrdata
        0x00000000004c9240 - 0x00000000004cb3f0 is .data
        0x00000000004cb400 - 0x00000000004f86b0 is .bss
        0x00000000004f86c0 - 0x00000000004fd990 is .noptrbss
        0x0000000000400f9c - 0x0000000000401000 is .note.go.buildid
(gdb) 

可以看到程序的Entry point为 0x45cd80, 对应分段的地址范围,可以算出来程序0x45cd80在.text段。添加断点,可以看到 Entry point: 0x45cd80 对应的内容

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
(gdb) b *0x45cd80
Breakpoint 1 at 0x45cd80: file /data/opt/go/src/runtime/rt0_linux_amd64.s, line 8.
(gdb) 

可以得出这个go程序的入口在 file /data/opt/go/src/runtime/rt0_linux_amd64.s, line 8.

在gdb中通过

  • b-设置断点,
  • run-启动程序,
  • n-逐步执行

可以看到程序的引导过程

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
rt0_linux_amd64.s 
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "textflag.h"

TEXT _rt0_amd64_linux(SB),NOSPLIT,$-8
 JMP _rt0_amd64(SB)

TEXT _rt0_amd64_linux_lib(SB),NOSPLIT,$0
 JMP _rt0_amd64_lib(SB)

可以看到这部分没有太多内容,程序直接跳转执行到全局符号 _rt0_amd64(SB)

_rt0_amd64:_rt0_amd64

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// _rt0_amd64 is common startup code for most amd64 systems when using
// internal linking. This is the entry point for the program from the
// kernel for an ordinary -buildmode=exe program. The stack holds the
// number of arguments and the C-style argv.
TEXT _rt0_amd64(SB),NOSPLIT,$-8
 MOVQ 0(SP), DI // argc
 LEAQ 8(SP), SI // argv
 JMP runtime·rt0_go(SB)

这段代码把参数个数argc复制到DI寄存器。把参数值地址argv拷贝到SI寄存器。关联知识:我们分析的是amd64的源码,汇编指令按64bit寻址,每次操作8个字节的数据。这里使用的汇编指令都带一个Q表示操作的是8个字节,如果是32bit则指定为MOVL、LEAL等,表示操作4个字节) 这里有个问题,就是为什么起始时0(SP)和8(SP)是argc和argv。这里看了一些文章结合自己的理解,应该是操作系统的约定(需要进一步确认,留个坑后续补充)

_rt0_amd64:rt0_go

rt0_go 内容比较多,比较复杂, 逐段分析。

命令行参数拷贝

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// asm_amd64.s

// Defined as ABIInternal since it does not use the stack-based Go ABI (and
// in addition there are no calls to this entry point from Go code).
TEXT runtime·rt0_go<ABIInternal>(SB),NOSPLIT,$0
 // copy arguments forward on an even stack
 MOVQ DI, AX  // argc,
 MOVQ SI, BX  // argv
 SUBQ $(4*8+7), SP  // 2args 2auto
 ANDQ $~15, SP // 最后16位清0,实现16字节对齐
 MOVQ AX, 16(SP)
 MOVQ BX, 24(SP)

 // ......  

这一段代码是做命令行参数的拷贝和栈顶指针SP偏移的。

前面两行是把argc、argv拷贝到寄存器AX、BX。然后SP指针向下移动4*8+7个字节,预留空间用来存放命令行参数

“栈空间的寻址是自高地址向低地址

我们看下这个4*8+7的值是怎么来的。实际上是2*8+2*8+7 引导程序先把argc和argv下移,即第一个2*8。即最终的SP+16和SP+4, 第二个2*8字节,在这里并未填充值,它是用来后面给G0传递参数的,让G0启动向一个普通的调用一样。SP+0和SP+8 可以在rt0_go的后面部分看到赋值

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
TEXT runtime·rt0_go<ABIInternal>(SB),NOSPLIT,$0
 ......
ok:
 ......
 MOVL 16(SP), AX  // copy argc
 MOVL AX, 0(SP)
 MOVQ 24(SP), AX  // copy argv
 MOVQ AX, 8(SP)
 ......

多偏移的7字节是哪里来的,还没有搞懂。看到很多材料写的是为了后面的16字节对齐,但是如果仅仅只是为了16字节对齐,后面的ANDQ $~15, SP看起来就已经足够了。先留个坑,后面搞懂了回来补充。

关于16字节对齐 关联知识:CPU有一组SSE指令,这些指令中出现的内存地址必须是16的倍数。在 SUBQ $(4*8+7), SP之前,因为64bit机器的寻址是8字节为单元, SP对应的内存地址有2中可能:

  • 0x*****0:最后一位是0,本身是16字节对齐
  • 0x*****8:最后一位是8,不是16字节对齐。

如果是0x*****0这种情况,那么4*8本身就是16字节对齐的,不需要额外操作。单是如果是0x*****8这种情况的话,就需要做16字节对齐。

G0执行栈初步初始化

继续往下分析

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
TEXT runtime·rt0_go<ABIInternal>(SB),NOSPLIT,$0
 ......
 // create istack out of the given (operating system) stack.
 // _cgo_init may update stackguard.
 MOVQ $runtime·g0(SB), DI   // DI = g0
 LEAQ (-64*1024+104)(SP), BX    
 MOVQ BX, g_stackguard0(DI)  // g0.stackguard0 = SP + (-64*1024+104)
 MOVQ BX, g_stackguard1(DI)  // g0.stackguard1 = SP + (-64*1024+104)
 MOVQ BX, (g_stack+stack_lo)(DI) // g0.stack.stack_lo = SP + (-64*1024+104)
 MOVQ SP, (g_stack+stack_hi)(DI) // g0.stack.stack_hi = SP + (-64*1024+104)

    // find out information about the processor we're on,确定CPU处理器信息
    MOVL $0, AX
    CPUID
    MOVL AX, SI
    CMPL AX, $0
    JE nocpuinfo

这一部分是初始化g0的执行栈。参考结构体g的定义:https://github.com/golang/go/blob/9baddd3f21230c55f0ad2a10f5f20579dcf0a0bb/src/runtime/runtime2.go#L404

TLS 线程本地存储

代码链接

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 LEAQ runtime·m0+m_tls(SB), DI // DI = m0.tls, 
 CALL runtime·settls(SB)     // 设置TLS, 还没完全看懂,待进一步分析

 // store through it, to make sure it works
 get_tls(BX)
 MOVQ $0x123, g(BX)
 MOVQ runtime·m0+m_tls(SB), AX
 CMPQ AX, $0x123    // 判断 TLS 是否设置成功
 JEQ 2(PC)       // 如果相等则向后跳转两条指令
 CALL runtime·abort(SB)   // 使用 INT 指令执行中断
ok:

关联g0和m0

代码链接

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 // set the per-goroutine and per-mach "registers"
 // g0和m0是全局变量,先获取他们的地址分别存在寄存器CX和AX
 get_tls(BX)
 LEAQ runtime·g0(SB), CX
 MOVQ CX, g(BX)
 LEAQ runtime·m0(SB), AX

 // 关联g0和m0 
 // save m->g0 = g0
 MOVQ CX, m_g0(AX)
 // save m0 to g0->m
 MOVQ AX, g_m(CX)

运行时检查

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 CLD    // convention is D is always left cleared
 CALL runtime·check(SB)

runtime·check(SB)的代码链接, check会进行各种检查,如果检查未通过,直接抛出异常,一般是编译过程发生了错误。系统级的初始化代码链接

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 MOVL 16(SP), AX  // copy argc
 MOVL AX, 0(SP)
 MOVQ 24(SP), AX  // copy argv
 MOVQ AX, 8(SP)
 CALL runtime·args(SB) // 参数的初始化
 CALL runtime·osinit(SB) // 
 CALL runtime·schedinit(SB)

前面四行是做argc和argv的再一次拷贝。(这里没搞懂为什么需要做多次的参数拷贝,看到一些解释是为了让g0模拟普通goroutine调用)

后面三行是3个函数调用

runtime.args

func args() 代码链接

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func args(c int32, v **byte) {
 argc = c
 argv = v
 sysargs(c, v) 
}

把参数存放在全局变量argc和argv中,供其他初始化函数使用。func sysargs()的代码链接sysargs()用于将一些内核级别的信息存放到执行栈中(是放在主调的栈中) 对这方面感兴趣的可以搜索golang linux 函数调用栈相关的内容

runtime·osinit

代码链接 osinit()

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func osinit() {
 ncpu = getproccount()        // 获取CPU核心数
 physHugePageSize = getHugePageSize()   // 获取内存物理页代销
 ......
 osArchInit() //  目前看是个空函数
}

运行时组件初始化

runtime·schedinit(SB) 开始是golang 运行时组件相关的初始化代码链接

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 CALL runtime·schedinit(SB)

schedinit的代码链接

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// The new G calls runtime·main.
func schedinit() {
 
   // 各种加锁
   ......

 // raceinit must be the first call to race detector.
 // In particular, it must be done before mallocinit below calls racemapshadow.
 _g_ := getg()
 if raceenabled {
  _g_.racectx, raceprocctx0 = raceinit()
 }

 sched.maxmcount = 10000

 // The world starts stopped.
 worldStopped()

   // 栈、内存分配器、调度器相关初始化
 moduledataverify()
 stackinit()   // 初始化执行栈
 mallocinit()  // 初始化内存分配器malloc
 fastrandinit() // must run before mcommoninit
 mcommoninit(_g_.m, -1)   // 初始化当前系统线程,只完成部分通用的初始化 
 cpuinit()       // must run before alginit
 alginit()       // maps must not be used before this call
 modulesinit()   // provides activeModules
 typelinksinit() // uses maps, activeModules
 itabsinit()     // uses activeModules

 sigsave(&_g_.m.sigmask)
 initSigmask = _g_.m.sigmask

 goargs()
 goenvs()
 parsedebugvars()
 gcinit()

   // 创建 P, 通过 CPU 核心数和 GOMAXPROCS 环境变量确定 P 的数量
 lock(&sched.lock)
 sched.lastpoll = uint64(nanotime())
 procs := ncpu
 if n, ok := atoi32(gogetenv("GOMAXPROCS")); ok && n > 0 {
  procs = n
 }
 if procresize(procs) != nil {
  throw("unknown runnable goroutine during bootstrap")
 }
 unlock(&sched.lock)

 // World is effectively started now, as P's can run.
 worldStarted()

 // For cgocheck > 1, we turn on the write barrier at all times
 // and check all pointer writes. We can't do this until after
 // procresize because the write barrier needs a P.
 if debug.cgocheck > 1 {
  writeBarrier.cgo = true
  writeBarrier.enabled = true
  for _, p := range allp {
   p.wbBuf.reset()
  }
 }

 if buildVersion == "" {
  // Condition should never trigger. This code just serves
  // to ensure runtime·buildVersion is kept in the resulting binary.
  buildVersion = "unknown"
 }
 if len(modinfo) == 1 {
  // Condition should never trigger. This code just serves
  // to ensure runtime·modinfo is kept in the resulting binary.
  modinfo = ""
 }
}

主goroutine启动

代码链接

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
 // create a new goroutine to start program
 MOVQ $runtime·mainPC(SB), AX  // entry, 主 goroutine 入口地址runtime.main
 PUSHQ AX
 PUSHQ $0   // arg size
 CALL runtime·newproc(SB)  // 创建执行单元,创建g
 POPQ AX
 POPQ AX

 // start this M
 CALL runtime·mstart(SB)   // 开始启动调度器的调度循环

 CALL runtime·abort(SB) // mstart should never return
 RET

 // Prevent dead-code elimination of debugCallV1, which is
 // intended to be called by debuggers.
 MOVQ $runtime·debugCallV1<ABIInternal>(SB), AX
RET

newproc(SB)的代码链接, newproc 会创建一个g

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
func newproc(siz int32, fn *funcval) {
 argp := add(unsafe.Pointer(&fn), sys.PtrSize)
 gp := getg()
 pc := getcallerpc()
 systemstack(func() {
  newg := newproc1(fn, argp, siz, gp, pc)

  _p_ := getg().m.p.ptr()
  runqput(_p_, newg, true)

  if mainStarted {
   wakep()
  }
 })
}

mstart()

runtime·mstart 相对比较复杂,后面新开一篇文章介绍。主要调用链路是

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
mstart()==>mstart1()==>schedule()

主要功能是启动调度器,在shedule()中进行循环调度

封面图:

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2023-09-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 海天二路搬砖工 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
PIE-engine 教程 ——提取黄河流域/山西省1980—2018年流域降水量并对比分析
这里面我们首先要上传我们自己的研究区,然后加载每一年的数据降水数据,通过系数转化,完成正常降水量的展示,我们通过对reduceregion的统计,分别算出平均降水量,分辨率设定为1000米,最后加载影像的chart折线图,用于存放坐标横轴时间和纵轴的对象(降水),这里我们首先看一下降水数据
此星光明
2024/02/02
2360
PIE-engine 教程 ——提取黄河流域/山西省1980—2018年流域降水量并对比分析
用python对汽车油耗进行数据分析(anaconda python3.6完全跑通)
编者按:前两天我们微信发了一篇文章《用python对汽车油耗进行数据分析》,有一网友学习后用python3.6重新跑了一下数据,请大家比较阅读。PPV课致力于为大家提供一个开放、分享、进步的数据科学社区,欢迎小伙伴们给我们分享你的学习心得和博客文章,有你的鼓励和支持,我们会做的更好。投稿请联系QQ149104196。 正文: 1.下载汽车油耗数据集并解压 下载地址:https://www.fueleconomy.gov/feg/download.shtml vehiclesData.py: #encodi
小莹莹
2018/04/23
1K0
用python对汽车油耗进行数据分析(anaconda python3.6完全跑通)
[Setting]给VS2008扩展BCGControlBar库
原文链接:http://blog.csdn.net/humanking7/article/details/50733036
祥知道
2020/03/10
9020
最全Windows代系介绍,迎接Windows 2020,回顾Windows XP经典
Windows 在历史上曾出现过的产品可以划分为三个阶段,分别为:以 DOS 为基础的 Windows,以 Windows 9x 为代表的 Windows,以 NT 为基础开发的 Windows。
Windows技术交流
2020/03/24
6.2K8
系统内核溢出提权
在后渗透测试阶段,权限提升是一个绕不开的话题,其中"系统内核溢出提权"因其利用便捷成为了最为常用的方法,在使用该方法提权时我们只需要去查看目标系统中打了那些系统补丁,之后去找补丁的"互补"补丁,并利用对应的提权类的漏洞实现权限提升,本篇文章主要围绕"系统内核溢出提权"的一些方法、思路进行简易介绍~
Al1ex
2021/03/29
1.6K0
系统内核溢出提权
Google Earth Engine——清华Tsinghua/FROM-GLC/GAIA/v10该数据集包含1985年至2018年全球不透水表面积的年度变化信息,分辨率为30米
This dataset contains annual change information of global impervious surface area from 1985 to 2018 at a 30m resolution. Change from pervious to impervious was determined using a combined approach of supervised classification and temporal consistency checking. Impervious pixels are defined as above 50% impervious. The year of the transition (from pervious to impervious) can be identified from the pixel value, ranging from 34 (year: 1985) to 1 (year: 2018). For example, the impervious surface in 1990 can be revealed as the pixel value greater than 29 (see the lookup table). This dataset is temporally consistent, following the conversion from pervious (e.g., non-urban) to impervious (e.g., urban) monotonically. For more information about the mapping approach and assessment, see Annual maps of global artificial impervious area (GAIA) between 1985 and 2018 (Gong et al. 2020).该数据集包含1985年至2018年全球不透水表面积的年度变化信息,分辨率为30米。从透水到不透水的变化是使用监督分类和时间一致性检查的综合方法确定的。不透水的像素被定义为超过50%的不透水。转变的年份(从透水到不透水)可以从像素值中确定,范围从34(年份:1985)到1(年份:2018)。例如,1990年的不透水表面可以显示为像素值大于29(见查询表)。这个数据集在时间上是一致的,按照从透水(如非城市)到不透水(如城市)的转换单调地进行。关于制图方法和评估的更多信息,见1985-2018年间全球人工不透水面积(GAIA)的年度地图(Gong等人,2020)。
此星光明
2024/02/02
2530
Google Earth Engine——清华Tsinghua/FROM-GLC/GAIA/v10该数据集包含1985年至2018年全球不透水表面积的年度变化信息,分辨率为30米
windows系统和Office软件的KMS密钥(GVLK)
系统名称后面带个N的,代表移除了某些功能,例如:Windows Media Player, Groove Music, Movies & TV, Voice Recorder, Skype等 https://support.microsoft.com/en-us/help/3010081/media-feature-pack-for-windows-10-n-and-windows-10-kn-editions 名词 解释 Datacenter 数据中心版 Standard 标准版 Professional
jwj
2022/05/18
3.7K0
可视化操作系统成主流(29k字)
科学Sciences导读:纵观计算机历史,操作系统与计算机硬件的发展息息相关。本文从操作系统演进的五个阶段(9k字)、早期操作系统的发展阶段(10k字)、硬件兼容的UNIX起源和谱系(11k字)、可视化操作系统成主流(29k字)、操作系统功能和技术简介(4k字)等五个方面,介绍计算机操作系统的演进、谱系和产品发展史。计算机发展过程中,出现过许多操作系统:DOS、MacOS、Windows、Unix、Linux、Free BSD等。关键词:计算机,操作系统,OS,Multics,Unics,Unix,Minux,Linux,Xenix、OS/2、Dos,Windwows,iOS,Android,演进,谱系。赞赏支持科普作者后,公号输入栏发送“操作系统史”获取本PDF资料,下载学习科技知识。
秦陇纪
2019/07/15
2.8K0
可视化操作系统成主流(29k字)
微软安全公告—2016年10月
微软于北京时间2016年10月11日发布了10个新的安全公告,其中6个为严重等级,4个为重要等级。本次更新主要修复Windows、InternetExplorer、Office、MicrosoftOffice Services 和Microsoft .NET Framework、AdobeFlash Player、Microsoft Edge等组件的安全漏洞。我们推荐您安装所有更新,对于暂时只采用部分更新的用户,我们推荐您首先部署等级为“严重”的安全公告。安全公告每月更新一次,旨在解决严重的漏洞问题。
嘉为蓝鲸
2018/12/21
7440
提权EXP列表
请注意,本文编写于 1307 天前,最后修改于 697 天前,其中某些信息可能已经过时。
Xcnte
2021/12/14
1.7K0
人人网登录界面[通俗易懂]
<!DOCTYPE html> <html> <head> <meta charset=”UTF-8″> <title>人人网注册页面</title> </head> <body> <p><img src=”image/renren_titile.gif” /></p> 人人网,中国<strong>最真实、最有效</strong>的社会平台,加入人人网,找回老朋友,结交新朋友。<br /> <p>电子邮箱:<input type=”email” name=”e” maxlength=”50″ /></p> <p>设置密码:<input type=”password” name=”pass” maxlength=”16″ /></p> <p>真实姓名:<input type=”text” name=”x” maxlength=”8″> </p> <p> 性别:<input type=”radio” value=”boy” name=”sex” checked />男 <input type=”radio” value=”girl” name=”sex” />女 </p> <p> 生日:<select name=”birthday” size=””> <option value=””>1980</option> <option value=””>1981</option> <option value=””>1982</option> <option value=””>1983</option> <option value=””>1984</option> <option value=””>1985</option> <option value=””>1986</option> <option value=””>1987</option> <option value=””>1988</option> <option value=””>1989</option> <option value=””>1990</option> <option value=”” selected>1991</option> <option value=””>1992</option> <option value=””>1993</option> <option value=””>1994</option> <option value=””>1995</option> <option value=””>1996</option> <option value=””>1997</option> <option value=””>1998</option> <option value=””>1999</option> <option value=””>2000</option> <option value=””>2001</option> <option value=””>2002</option> <option value=””>2003</option> <option value=””>2004</option> <option value=””>2005</option> <option value=””>2006</option> <option value=””>2007</option> <option value=””>2008</option> <option value=””>2009</option> <option value=””>2010</option> <option value=””>2011</option> <option value=””>2012</option> <option value=””>2013</option> <option value=””>2014</option> <option value=””>2015</option> <option value=””>2016</option> <option value=””>2017</option> </select>年 <select name=”” size=””> <option value=””>1</option> <option value=””>2</option> <option value=””>3</option> <o
全栈程序员站长
2022/09/20
2.4K0
WPF桌面端开发-获取系统版本,位数等信息
无论哪种方式获取系统版本,Win11获取到的都是Win10,但是版本号的方式可以通过构建号来判断Win11。
码客说
2023/07/11
7180
WPF桌面端开发-获取系统版本,位数等信息
操作系统的发展史(DOS/Windows篇)
操作系统的最强入门科普(Unix/Linux篇) 上一篇文章,小枣君介绍了Unix和Linux操作系统的诞生和发展。今天这篇,我再来说说微软的DOS和Windows系列。
鲜枣课堂
2023/08/21
6410
操作系统的发展史(DOS/Windows篇)
Microsoft 安全公告摘要(2015 年 10 月)
Microsoft 安全公告摘要(2015 年 10 月) 10(共 16)对本文的评价是有帮助 - 评价此主题 发布日期:2015 年 10 月 13 日 | 更新时间:2015 年 10 月 15 日 版本: 1.2 本页内容 执行摘要 利用指数 受影响的软件 检测和部署工具及指导 鸣谢 其他信息 本公告摘要列出了 2015 年 10 月发布的安全公告。 有关在 Microsoft 安全公告发布时如何收到自动通知的信息,请访问 Microsoft 技术安全通知。 Microsoft 还会提供相关信息,帮
逸鹏
2018/04/09
1.8K0
微软安全公告—2016年9月
微软于北京时间2016年9月13日发布了14个新的安全公告,其中7个为严重等级,7个为重要等级。本次更新主要修复Windows、Internet Explorer、Office、Microsoft Office Services 和 Microsoft .NET Framework、Adobe Flash Player、Microsoft Edge等组件的安全漏洞。我们推荐您安装所有更新,对于暂时只采用部分更新的用户,我们推荐您首先部署等级为“严重”的安全公告。安全公告每月更新一次,旨在解决严重的漏洞问题。
嘉为蓝鲸
2018/12/21
7750
【史上最全】计算机的编年史
前几天我写算力简史的时候,顺便整理了一份计算机技术的编年史(将近一万字)。今天发给大家,以供参考。
鲜枣课堂
2023/08/21
1.1K0
【史上最全】计算机的编年史
Microsoft training Kits
Microsoft training kits对于开始学习一门新技术的时候是一个非常好的资料.下面是一些training kits列表: .NET Framework 3.5 Enhancements Training Kit Visual Studio 2008 and .NET Framework 3.5 Training Kit SQL Server 2008 Developer Training Kit Visual Studio 2010 and .NET Framework 4 Training
张善友
2018/01/19
9270
【建议收藏】各版本操作系统对.NET支持情况
镜像来源:MSDN, 我告诉你 - 做一个安静的工具站 (itellyou.cn)[1]
沙漠尽头的狼
2024/01/15
1.5K0
【建议收藏】各版本操作系统对.NET支持情况
微软安全公告—2016年4月
微软于北京时间2016年4月12日发布了13个新的安全公告,其中6个为严重等级,7个为重要等级。本次更新主要修复Windows、Internet Explorer、Office、Microsoft Office Services 和 Microsoft .NET Framework、Adobe Flash Player、Microsoft Edge等组件的安全漏洞。我们推荐您安装所有更新,对于暂时只采用部分更新的用户,我们推荐您首先部署等级为“严重”的安全公告。安全公告每月更新一次,旨在解决严重的漏洞问题。
嘉为蓝鲸
2018/12/21
1.1K0
数据库内核工程师必读论文清单
为了致敬中国数据库从业者一起走过的半个世纪,腾讯云 TVP《技术指针》与《明说三人行》策划了【中国数据库前世今生】系列记录片。此部纪录片共分为五期,时间跨度从上世纪八十年代至本世纪二十年代,涵盖五个十年。从 80 年代到 20 年代,每期将深入探讨该时代下的数据库演变历程,以及这些大趋势下鲜为人知的小故事。以下为 90 年代纪录片正片。----
腾讯云开发者
2024/07/05
3370
数据库内核工程师必读论文清单
推荐阅读
相关推荐
PIE-engine 教程 ——提取黄河流域/山西省1980—2018年流域降水量并对比分析
更多 >
目录
  • 环境说明
  • 使用gdb查看程序入口
  • _rt0_amd64:_rt0_amd64
  • _rt0_amd64:rt0_go
    • 命令行参数拷贝
    • G0执行栈初步初始化
    • TLS 线程本地存储
    • 关联g0和m0
    • 运行时检查
    • runtime.args
    • runtime·osinit
    • 运行时组件初始化
    • 主goroutine启动
    • mstart()
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档