微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

__init函数中的本地静态标识符会发生什么?

如何解决__init函数中的本地静态标识符会发生什么?

在应用程序编程中,static存储在.BSS部分中。而且与局部变量不同,它们不会在函数返回或类似于全局变量的情况下取消分配。


在Linux中,可以使用__init属性标记功能,并且在执行这些功能时,{strong}中的代码.text将被删除


我们假设有一个带有__init函数,并且具有static局部变量;会从static部分中取消分配那些.BSS当地用户吗,并从.text部分中分配功能吗?

是的,在static函数中声明__init变量,当然可能没有任何用处(提及的话),但是我想了解在幕后。

解决方法

如果某物被定义为static,则它必须在关联单元的整个生命周期中保持活动状态。唯一发生的事情是,您将无法在声明对象的函数之外的任何地方通过其原始名称引用该对象。因此,如果您没有在其他地方保存对该对象的引用,则该对象仍然可用,但是您将无法访问该对象(这可能被视为内存泄漏)。

谈论内核代码的唯一例外是__initdata宏,它将把变量放在特定的部分(.init.data)中,并在初始化完成后将其丢弃(就像{{1} })。在这种情况下,即使定义了.init,该变量也将消失,并且引用将变为无效。如果仅出于初始化目的需要某种复杂(大型)结构,并且希望在init函数中使用它后通过丢弃它来节省空间,则这很有用。

这是一个可行的示例:

static

在编译以上显示后,使用// SPDX-License-Identifier: GPL-3.0 #include <linux/init.h> // module_{init,exit}() #include <linux/module.h> // THIS_MODULE,MODULE_VERSION,... #include <linux/kernel.h> // printk(),pr_*() #ifdef pr_fmt #undef pr_fmt #endif #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt static unsigned *global_ptr; static unsigned global_var; static int global_initdata_var __initdata; static int __init my_init(void) { static unsigned local_var = 123; static unsigned local_initdata_var __initdata = 456; global_ptr = &local_var; global_var = local_initdata_var; return global_initdata_var; } static void __exit my_exit(void) { pr_info("%u %u\n",*global_ptr,global_var); } module_init(my_init); module_exit(my_exit); MODULE_VERSION("0.1"); MODULE_DESCRIPTION("Test module."); MODULE_AUTHOR("Marco Bonelli"); MODULE_LICENSE("GPL"); 查看.ko文件:

  • objdumplocal_var部分的init函数中定义(因为它已显式初始化为.data)。
  • {{1}中的{li> 123local_initdata_var (由于global_initdata_var),无论它们在何处定义。
  • .init.data部分中的全局非显式初始化的变量。
__initdata

插入/卸下模块的结果:

.bss

如您所见,/ # objdump -j .init.data -j .data -j .bss -D static_init.ko static_init.ko: file format elf64-littleaarch64 Disassembly of section .data: 0000000000000000 <local_var.20642>: 0: 0000007b .word 0x0000007b Disassembly of section .init.data: 0000000000000000 <local_initdata_var.20643>: 0: 000001c8 .word 0x000001c8 0000000000000004 <global_initdata_var>: 4: 00000000 .word 0x00000000 Disassembly of section .bss: 0000000000000000 <global_ptr>: ... 0000000000000008 <global_var>: 8: 00000000 .word 0x00000000 甚至在插入模块后仍然存在,并标记为/ # insmod static_init.ko / # cat /proc/kallsyms | grep static_init ffff800011ad9768 b static_init_done.7337 ffff800008ca0000 t $x [static_init] ffff800008ca0000 t my_exit [static_init] ffff800008ca2000 d $d [static_init] ffff800008ca2000 d local_var.20642 [static_init] ffff800008ca2348 b $d [static_init] ffff800008ca2348 b global_ptr [static_init] ffff800008ca2350 b global_var [static_init] ffff800008ca1028 r $d [static_init] ffff800008ca2040 d $d [static_init] ffff800008ca1040 r $d [static_init] ffff800008ca1040 r _note_6 [static_init] ffff800008ca2040 d __this_module [static_init] ffff800008ca0000 t cleanup_module [static_init] / # rmmod static_init [ 12.155152] static_init: 123 456 / # (本地数据符号),而变量用local_var定义(无论在哪里)不再存在。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。