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

Linux下c语言中main函数如何调用

当我们shell下执行一个程序时候,shell内部首先会用fork系统调用来新建一个进程,然后再用execve系统调用把目标程序加载到内存中,并将其参数及环境变量等压入栈中,之后再执行目标程序入口函数...也就是说,kernelexecve系统调用在加载完目标程序执行第一个函数,就是上面的_start函数。...exit (result);} 上面就是对应__libc_start_main函数,由上可见,该函数参数及其顺序和前面的_start函数里按照c语言calling convention准备参数及顺序一致...__libc_start_main函数执行了大段准备代码之后,最终调用了我们main函数。...main函数返回之后,将其结果赋值给result,然后再调用exit(result)作为该程序返回值。 至此,一个程序完整生命周期就结束了。 完。

3.2K20
您找到你想要的搜索结果了吗?
是的
没有找到

函数调用时栈如何变化

大家都知道函数调用是通过栈来实现,而且知道栈中存放着该函数局部变量。但是对于栈实现细节可能不一定清楚。本文将介绍一下Linux平台下函数如何实现。...栈帧结构 函数调用时候都是栈空间上开辟一段空间以供函数使用,所以,我们先来了解一下通用栈帧结构。...函数调用之前,调用者会为调用函数做准备。...函数调用时 进入sum函数,我们看到函数前两行: push %rbp mov %rsp,%rbp 这两条汇编指令含义:首先将rbp寄存器入栈,然后将栈顶指针rsp赋值给rbp。...通过栈结构,可以知道,rbp上面就是调用函数调用调用函数下一条指令执行地址,所以需要赋值给rip,来找回调用函数指令执行地址。

3K21

C语言ARM中函数调用时,栈如何变化

r0-r3 用作传入函数参数,传出函数返回值。子程序调用之间,可以将 r0-r3 用于任何用途。调用函数返回之前不必恢复 r0-r3。...---如果调用函数需要再次使用 r0-r3 内容,则它必须保留这些内容。 2. r4-r11 用来存放函数局部变量。如果调用函数使用了这些寄存器,它在返回之前必须恢复这些寄存器值。...调用函数返回之前不必恢复 r12。 4. 寄存器 r13 栈指针 sp。它不能用于任何其它用途。sp 中存放退出调用函数时必须与进入时值相同。 5....寄存器 r14 链接寄存器 lr。如果您保存了返回地址,则可以调用之间将 r14 用于其它用途,程序返回时要恢复 6. 寄存器 r15 程序计数器 pc。它不能用于任何其它用途。...1.程序在内存分布区域 2.全局变量m赋值 3.保存进入main之前栈底, fp-sp之间当前函数栈 4.函数main栈已经准备好了 5.i入栈 6.j入栈 7.准备函数fun调用, 形参反向入栈

13.5K83

如何解决--渲染函数之外调用插槽问题

本文本中,将会解释这个错误背后原因以及如何解决这个问题。 插槽调用需要发生在渲染函数或模板中。要抑制这个错误,我们只需要把代码移到一个计算属性或从模板或渲染函数调用方法中。...如何确保 Vue 插槽跟踪依赖 接下来,我们分析下可以做些什么来确保我们插槽有一个响应式跟踪系统,确保不会更新失败 通过确保我们调用发生在渲染函数和模板中,问题就可以解决了,正如错误信息中提到那样...第一种使用渲染函数调用插槽函数,第二种使用vue单文件组件部分。...事实上,为了消除警告并确保我们组件中跟踪依赖关系,我们需要确保插槽调用发生在HTML中(随后框架编译成一个渲染函数)。...代码部署可能存在BUG没法实时知道,事后为了解决这些BUG,花了大量时间进行log 调试,这边顺便给大家推荐一个好用BUG监控工具 Fundebug。

3.2K10

【Android 逆向】函数拦截原理 ( 通过修改 GOT 全局偏移表拦截函数 | 通过实际调用函数中添加跳转代码实现函数拦截 )

文章目录 一、通过修改 GOT 全局偏移表拦截函数 二、通过实际调用函数中添加跳转代码实现函数拦截 一、通过修改 GOT 全局偏移表拦截函数 ---- 使用 GOT 全局偏移表 拦截函数 , 只需要将...: ① 调用拦截函数 : 真实调用实际 拦截函数 , 只是 对参数 或 返回值 进行一系列处理 , 然后返回 返回值 ; ② 不调用拦截函数 : 也可以不调用 拦截函数 , 自己实现一个新逻辑..., 根据该函数地址 , 可以直接调用函数 , 这样就完美的避开了 GOT 全局偏移表 , 而执行函数 ; 因此 , 使用 GOT 表拦截函数并不能保证 100% 成功 ; 二、通过实际调用函数中添加跳转代码实现函数拦截...---- 实际调用函数 中 , 添加 跳转代码 , 跳转到 拦截函数 中 , 然后 拦截函数 调用 处理函数 , 处理函数调用真正实际函数 , 返回一个返回值 ; 该跳转代码添加方式..., 处理函数 调用 拦截 实际函数时 , 这个实际函数中 开始代码 我们插入 跳转代码 , 真实调用时 , 一定要将 跳转代码 恢复成原来状态 然后才能继续调用 ; 该方法 100% 可以执行成功

1.8K20

怎么sequence中调用agent中函数以及如何快速实验你想法?

“一条鱼”就是题目中那个问题本身:“UVM中怎么sequence中调用agent中函数”。这个问题很多同学猛听到可能还是会有一些懵,反应不出一个优雅解决方法。...并且定义了名叫topmodule,核心就58行一句话,通过run_test启动jerry_base_test。 我们再明确下要解决问题“怎么sequence中调用agent中函数?”...顺便提一下,37行,通过p_sequencer调用了jerry_sequencer(代码段1)中定义hello()函数。如果其中句子打印成功,说明我们此时p_sequencer机制触发成功。...终于,40行,我们通过agt句柄,调用jerry_agent中函数hi()。如果成功打印其中字符串就说明我们实现了我们目标。...运行成功,屏幕上果然会打出hello()和hi()函数字符串: hello,how are you! hi,I’m fine,thank you~and you?

2.5K40

Meta 无服务器平台如何做到每天处理数万亿次函数调用

两篇论文介绍了两个完全不同系统,因此,如果用谷歌搜索“XFaaS”,则需要知道,本文讨论该系统 Meta 版本。...调度器与 DurableQ 通信: 执行成功时发送一条 ACK 消息。然后函数调用就会从 DurableQ 中永久删除。 执行成功发送一条 NACK 消息。... XFaaS 系统中,使用相同编程语言函数相互隔离性,有专用运行时和工作者进程池。 该系统设计旨使任何 worker 都能立即执行函数,而不会出现任何初始化延迟。...JIT 编译有以下三个执行阶段: 由几个 worker 测试新代码; 由 2% worker 进一步测试代码;有些执行 JIT 编译性能分析; JIT 接收到函数调用请求之前完成,消除了延迟。...利用协作式 JIT 编译,worker 函数代码更新只需 3 分钟就能达到每秒最大请求数,而不使用 JIT 编译则需要 21 分钟。

27810

浅析golang中defer

语句调用一个函数,该函数执行延迟到defer语句所处函数return之后再执行 defer、return、返回值三者执行逻辑应该是:return最先执行,负责将结果写入返回值中;接着defer开始执行...所以可以用defer语句资源打开马上调用defer去释放资源,可以避免忘记释放资源。...", a) a++ } //结果 defer 1 根据前面介绍defer会在return之后再执行,为什么还是打印1呢,原因defer函数defer语句执行那一刻就已经确定下来了,即此时要打印什么值已经确定好了...因为此时给def函数传递a地址,a++执行把a地址上值+1,然后把经过+1a地址上值赋值给b,最后defer打印出来a地址上值经过+1值,所以最后结果为2,现在试着把地址打印出来...会在匿名函数结束时候得到执行,就不会出现之前资源没有释放情况 4.defer性能消耗 使用defer调用函数会比直接调用函数开销更大,测试一下 func def1() (a int) { a =

46620

Go 函数健壮性、panic异常处理、defer 机制

更新代码中,当 bar 函数调用 panic 函数触发异常,bar 函数执行就会被中断。...但这一次,代码执行流回到 bar 函数调用者之前,bar 函数 panic 之前就已经设置成功 derfer 函数就会被执行。...下面有关 defer 函数介绍和如何使用它来简化函数实现内容: 4.1 defer 函数介绍 延迟执行defer 允许将一个函数或方法调用推迟到当前函数返回之前执行,无论正常返回还是由于 panic...不仅限于函数调用defer 不仅可以用于函数调用,还可以用于方法调用,匿名函数执行等。 4.2 使用 defer 简化函数实现 对函数设计来说,如何实现简洁目标一个大话题。...前者测量带有 defer 函数执行性能,后者测量不带有 defer 函数执行性能。 Go 1.13 前版本中,defer 带来开销还是很大

28320

defer如何遍历执行

今天这篇也来尝试一下这种写法,不过,我们先从一个小主题开始:defer 链表如何遍历并执行。 关于 defer 源码分析文章,网络上也有很多。...会在函数里写上多个 defer 语句, defered 函数,以“先进出”顺序, RET 指令前得以执行一条函数调用链中,多个函数中会出现多个 defer 语句。...这只是执行了一个 defered 函数,这条链上其他 defered 函数,该如何得到执行呢?...图中 return address 表示子函数执行完毕,返回到上层函数调用函数语句下一条要执行指令,它属于 caller 栈帧。而调用 BP 则属于函数栈帧。...答案:unsafe.Pointer(&arg0)。我们知道,arg0 deferreturn 函数参数,我们又知道 Go 汇编中,一个函数参数由它主调函数准备

61710

Go语言中常见100问题-#47 Ignoring how defer arguments and receivers ...

参数计算求值 为了解释清楚defer语句中,参数如何计算使用,下面通过一个具体例子进行说明。一个函数调用foo和bar两个函数,与此同时,根据执行情况设置处理状态。...于是可以采用下面的方法2 方法2采用闭包,闭包就是匿名函数内部使用函数变量。将参数传给defer调用函数会被立即执行,然而,闭包函数中使用外部变量函数执行时候才会计算求值。...下面例子说明了defer+闭包如何工作,闭包将引用两个变量,一个作为函数参数,另一个函数体内直接使用。...因为,defer将使用sid值为foo来延迟执行,所以程序输出foo. 相反,如果接收器指针类型,调用defer,然后对接收器字段值进行修改,defer函数执行时候,修改字段值。...但是,它复制指针值。因此,对指针引用结构所做任何更改在延迟函数执行可见。所以上面的程序会输出bar. 总结,函数或方法上调用defer时,调用参数会立即被计算。

55420

Golang中巧用defer进行错误处理

一个函数中,当创建新资源失败时,则要清理所有前面已经创建成功资源,这使得函数中有了重复代码坏味道,比如destroyResource1函数调用了3次,destroyResource2函数调用了2...重构一:一个defer + 多个flag Golang提供了一个很好用关键字defer,当包含defer函数执行完毕时(不管通过return正常结束,还是由于panic导致异常结束),defer...语句才调用。...,虽然消除了重复,但是引入了太多flag: flag表示函数是否执行成功,即flag为true时表示函数执行成功,否则表示函数执行失败;defer语句中,只有flag为false时才需要统一清理资源...当err引用或指针和destroy操作都需要入栈时,defer后面必须一个闭包调用。我们知道,对于闭包参数值传递,而对于外部变量却是引用传递。

2.1K70

Go常见错误集锦 | 循环内部使用defer正确姿势

具体可参考我之前关于defer文章使用defer释放资源和你知道defer参数和接收者如何取值吗两篇文章。 本文给大家介绍一些使用循环语句内部使用defer会遇到坑以及如何避免。...下面一个循环中打开一组文件函数例子。函数中,会从一个通道中不断接收文件路径。然后通过遍历该通道,打开对应路径文件,然后使用完毕关闭该文件资源。...我们知道defer调用是在其所在函数返回时候才会发生该示例中,defer调用不是每次迭代结束,而是readFiles函数返回时。...函数返回时,函数defer就会被立即调用,也就是循环每个迭代完成就会立即调用。...相比较而言个人觉得还是第一种方式更好,符合面向对象单一职责原则。即一个函数只干一件事。这样也利于单元测试。 总之,实际编程过程中,谨记defer执行在其所在函数返回时才执行这条原则。

79020

深入 Go 语言 defer 实现原理

上面所说,如果一个defer调用函数一个 function literal,也就是说是闭包或者匿名函数,并且调用 defer函数时一个有名返回值(named result parameters...func() { i++ }() return i } 因为匿名返回值函数return执行声明,因此defer语句中只能访问有名返回值函数,而不能直接访问匿名返回值函数。...从上面的分析中基本也回答了defer 可以修改有名返回值函数返回值如何做到,答案其实就是defer调用过程中传递 defer 参数一个返回值指针,所以最后 defer执行时候会修改返回值...匿名函数返回值调用 那么如果匿名返回值函数如何传递呢?...主要通过堆上分配来讲解 defer 函数调用如何,如:函数调用来理解" defer 参数传递"、"多个 defer 语句如何执行"、"以及 defer、return、返回值执行顺序怎样"等这几个问题

74240

golang-defer

这里提到了defer调用参数会立即计算,但在周围函数返回之前不会执行函数调用。 以及延迟函数调用压入堆栈。当函数返回时,其延迟调用以后进先出顺序执行。...它有如何特点 所在函数中,它在 return 或 panic 或 执行完毕 调用 多个 defer,它们调用顺序,为栈形式。...先进出,先定义调用 看下面几个例子: 计算defer语句时,将计算延迟函数参数。在此示例中,延迟Println调用时计算表达式“i”。函数返回,延迟调用将打印“0”。...func a() { i := 0 defer fmt.Println(i) i++ return } 周围函数返回,延迟函数调用以后进先出顺序执行。...即使 defer 函数中,它作为函数参数,定义时候也会首先调用函数进行求值 // 按照正常顺序,calc("10", a, b) 首先调用求值。

89010

Go中defer5 个坑-第一部分

#1 — defer nil 函数 如果一个延迟函数赋值为 , 运行时 异常会发生在外围函数执行结束而不是 函数调用时候。 例子 输出结果 发生了什么?...名为 func 函数一直运行至结束,然后 函数会被执行且会因为值为 而产生 异常。然而值得注意声明没有问题,因为在外围函数运行完成它才会被调用。...输出结果 糟糕处理方式: 即便这种处理方式很糟,但我还是想告诉你如何不用变量来解决这个问题,因此,我希望你能以此来了解 defer 亦或是 go 语言运行机制。...#4 — 执行块中使用 defer 你可能想要在执行执行结束执行在块内延迟调用函数,但事实并非如此,它们只会在块所属函数执行结束才被执行,这种情况适用于所有的代码块除了上文函数块例如,for...因为:延迟相对于一个函数而非一个代码块 例子 输出结果 上例延迟函数只会在函数执行结束运行,而不是紧接着它所在块(花括号内包含 defer 调用区域)执行,就像代码中演示那样,你可以使用花括号创造单独执行

1.1K50

Go语言中常见100问题-#53-54 Not handling an error & defer errors

notify() } func notify() error { // ... } 上面f函数调用notify函数,没有将返回值赋值给任何error变量,从语法层面来说,没有任何问题...然而从代码可维护性角度,这将会导致一些问题。假如一个新程序员在读到这段代码时候,他会猜测作者忘记处理notify返回值了呢还是特意忽略它?...前面讨论了函数返回errors值总是应该被处理。然而,本例中defer调用返回错误值却被忽略了。...代码如下,一旦rows.Close调用,它返回值将被赋值给外层getBalance函数返回值。...上述实现逻辑并不简单,预期效果 rows.Scan rows.Close 返回值 执行成功 执行成功 返回nil 执行成功 执行失败 返回rows.Close错误 执行失败 执行成功 期望返回rows.Scan

51720

Go 语言中 panic 和 recover 搭配使用

panic 是否已经 recover 了 aborted 表示当前 panic 是否中止 对于 pc 和 sp 自然就是我们熟知 pc 通用寄存器,汇编中指向当前运行指令下一条指令,sp...(*Logger).SetFlags(SB) 即是执行到我们调用 log 去设置参数 程序走到 panic 函数时候,实际上执行了 runtime.gopanic 函数,我们一起看看源码 代码中可以看到...panic 如何执行了,那么对于现在来研究 recover 如何落实 recover 还是同一个例子,咱们将 defer 部分代码注打开,来继续看看效果 func main() {...中校验 p.recovered 已处理,则执行 recovery 函数 recovery 函数中去处理对应寄存器值去维护上下文 最后我们可以看到最终调用 gogo 函数跳回原来调用位置 因此,当我们同一个协程中出现了...自然,表面上这样,其中对于寄存器各种数据处理涉及内容还是不少,不过这不在我们今天聊范畴中了 总结 至此,相信你已经知道了这些 为什么 panic 和 defer ,recover 配合使用时候要在同一个协程中了吧

17420
领券