今天在vmlinux上设置断点的时候出现4个地址, 超乎认知了, 仔细得看了一下原因

(gdb) b sched_clock
Breakpoint 1 at 0xffffffff8101cf00: sched_clock. (4 locations)
(gdb) i b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   <MULTIPLE>
1.1                         y     0xffffffff8101cf00 in sched_clock at arch/x86/kernel/tsc.c:75
1.2                         y     0xffffffff8101d4fd in tsc_save_sched_clock_state at arch/x86/include/asm/paravirt.h:192
1.3                         y     0xffffffff8101d555 in tsc_restore_sched_clock_state at arch/x86/include/asm/paravirt.h:192
1.4                         y     0xffffffff810b5c30 in sched_clock at kernel/sched/clock.c:71

仔细得看了一下第一个断点, 正常

unsigned long long sched_clock(void)
{return paravirt_sched_clock();
}
(gdb) disassemble sched_clock
Dump of assembler code for function sched_clock:0xffffffff8101cf00 <+0>:     push   %rbp0xffffffff8101cf01 <+1>:     mov    %rsp,%rbp
-------------------------------------------------------------------------------0xffffffff8101cf04 <+4>:     callq  *0xffffffff81a463c0
-------------------------------------------------------------------------------0xffffffff8101cf0b <+11>:    pop    %rbp0xffffffff8101cf0c <+12>:    retq
End of assembler dump.

看第二个使用的地方tsc_save_sched_clock_state

void tsc_save_sched_clock_state(void)
{if (!sched_clock_stable())return;cyc2ns_suspend = sched_clock();
}(gdb) disassemble tsc_save_sched_clock_state
Dump of assembler code for function tsc_save_sched_clock_state:0xffffffff8101d4f0 <+0>:     push   %rbp0xffffffff8101d4f1 <+1>:     mov    %rsp,%rbp0xffffffff8101d4f4 <+4>:     callq  0xffffffff810b5d30 <sched_clock_stable>0xffffffff8101d4f9 <+9>:     test   %eax,%eax0xffffffff8101d4fb <+11>:    je     0xffffffff8101d50b <tsc_save_sched_clock_state+27>
------------------------------------------------------------------------------0xffffffff8101d4fd <+13>:    callq  *0xffffffff81a463c0
------------------------------------------------------------------------------0xffffffff8101d504 <+20>:    mov    %rax,0xd1c935(%rip)        # 0xffffffff81d39e40 <cyc2ns_suspend>0xffffffff8101d50b <+27>:    pop    %rbp0xffffffff8101d50c <+28>:    retq
End of assembler dump.

可以看到函数tsc_save_sched_clock_state在调用sched_clock的时候, 因为tsc_save_sched_clock_state和sched_clock在同一个c文件里面, 就直接把函数sched_clock的肉嵌入进来了, 没有直接调用sched_clock, 为了和c语言的逻辑保持一致, 所以这些地方都需要被打上断点

第三个tsc_restore_sched_clock_state和第二个是一样的

第4个的代码是这样的

unsigned long long __attribute__((weak)) sched_clock(void)
{return (unsigned long long)(jiffies - INITIAL_JIFFIES)* (NSEC_PER_SEC / HZ);
}

是个弱符号, 但是从以前的知识来说, 弱符号在编译的时候会被强符号干掉, 在从o文件连接成elf文件的时候就没了, 为什么这个时候又出现了呢

readelf -s vmlinux |grep sched_clock\$9679: ffffffff819e8690    16 OBJECT  LOCAL  DEFAULT    8 __ksymtab_sched_clock9680: ffffffff819fc66a    12 OBJECT  LOCAL  DEFAULT   11 __kstrtab_sched_clock9681: ffffffff819f7ac0     8 OBJECT  LOCAL  DEFAULT   10 __kcrctab_sched_clock66460: ffffffff8101ce80   123 FUNC    GLOBAL DEFAULT    1 native_sched_clock67482: 000000003a26ed11     0 NOTYPE  GLOBAL DEFAULT  ABS __crc_sched_clock72418: ffffffff8101cf00    13 FUNC    GLOBAL DEFAULT    1 sched_clock

可以看到其实符号表里面只有一个sched_clock符号, 从地址上可以确定是gdb中的第一个符号, 那么这些信息存在哪里呢

一个有可能的猜想就是在debug section里面

把vmlinux的debug section去掉看看

$strip --strip-debug vmlinux.cpgdb vmlinux.cp(gdb) i b
Num     Type           Disp Enb Address            What
1       breakpoint     keep y   0xffffffff8101cf04 <sched_clock+4>

可以只剩一个了, 所以原因是vmlinux中的debug section的信息符号了符号表的信息, 这样看起来, 在gdb vmlinux的时候, 去掉debug section的时候, 有些函数调用信息会丢失, 光依赖符号表也不准确

gdb 设置一个函数, 出现4个断点的原因相关推荐

  1. C语言signal()函数(通过设置一个函数(回调函数)来处理捕获到异常信号时需要执行的操作)

    文章目录 描述 声明 参数 返回值 实例 附加解释 背景知识:C语言中signal函数简介及使用 描述 C 库函数 void (*signal(int sig, void (*func)(int))) ...

  2. 怎样设置一个函数C语言,C语言中怎样编写一个函数 如何在C语言中定义一个函数?...

    如何在C语言中定义一个函数?小编很想在你面前流泪最后却还是选择装作打个哈欠 为什么小编怎么定义函数都不正确呢? 总是说小编 表达语法错误在main函数中 小编们可以在头文件与main函数之间定义,并编 ...

  3. html中加定时器,怎么用HTML设置一个定时器

    用HTML设置一个定时器的方法:首先新建一个html页面,并设置一个按钮:然后给这个按钮绑定一个函数:接着设置一个变量用来保存定时器:最后在function里面写实现代码即可. 本文操作环境:wind ...

  4. gdb设置与清除断点

    四.设置与清除断点 break / b 可以用来在调试的程序中设置断点,该命令有如下四种形式 //使程序恰好在执行给定行之前停止 break line-number//使程序恰好在进入指定的函数之前停 ...

  5. gdb设置断点出现Cannot access memory at address的错误

    文章目录 1.0 问题描述 1.1 问题复现 2.0 2.1 静态链接库 2.2 动态链接库 2.3 PIC 1.0 问题描述 今天在给一个可执行c程序的entry point address设置断点 ...

  6. php检测一个变量是否设置函数,php如何判断变量是否有设置的函数

    php判断变量是否有设置的函数的方法:可以利用isset()函数来进行判断.isset()函数用于检测变量是否已设置并且非NULL.如果指定变量存在且不为NULL,则返回TRUE,否则返回FALSE. ...

  7. 练习2-6 编写一个函数setbits(x, p ,n, y),该函数返回对x执行下列操作后的结果值: 将x中从第p位开始的n个(二进制)位设置为y中最右边n位的值,x的其余各位保持不变。

    练习2-6 编写一个函数setbits(x, p ,n, y),该函数返回对x执行下列操作后的结果值: 将x中从第p位开始的n个(二进制)位设置为y中最右边n位的值,x的其余各位保持不变. 参考代码如 ...

  8. gdb 调试运行设置main函数参数

    TCPL中5.10为命令行参数,在程序运行前需要设置main函数中的参数,可是gdb调试时传递参数方法如下: 1. set args 可指定运行时参数.(如:set args 10 20 30 40 ...

  9. data为long 怎么设置vue_vue--为什么data属性必须是一个函数

    前言 老规矩,我们还是先说为什么. 问题描述:为什么在vue组件中,我们的data属性必须是一个函数,new Vue()中的data除外,因为new Vue中只有一个data属性. 原因:因为我们能抽 ...

最新文章

  1. 我在兰亭这三年完结篇之离开
  2. Linux 下 LaTeX 2018 安装与使用
  3. [CLR via C#]17. 委托
  4. Log4net中的RollingFileAppender解析
  5. php中jwt权限认证,php 后端实现JWT认证方法示例
  6. seL4 microkernel学习资料
  7. 关于线程池ThreadPoolExecutor使用总结
  8. 行为型模式:迭代器模式
  9. 怎么看待MYSQL的性能
  10. MyBatis association的两种形式——MyBatis学习笔记之四
  11. 飞思卡尔智能车参赛感受,以及开源自己搜集的资料
  12. 六年级计算机课件,六年级信息技术上册课件.ppt
  13. 2019-01-01T00:00:00.000Z 这种时间日期类型格式是属于:格林尼治时间
  14. C语言 - 输入x的值,输出y相应的值 x (x<1) y= 2x-1 (1≤x<10) 3x-11 (x≥10)
  15. 什么手势使用电子计算机比较快,手势功能
  16. 证明:无理数乘以非零的有理数仍然是无理数
  17. 学习编程的方法、软件和工具
  18. 倒计时器CountDownTimer使用
  19. ![CDATA[]]和转义字符
  20. Linux权限“suid”与“guid”设置

热门文章

  1. python培训深圳-深圳Python培训机构排名
  2. python处理数据的优势-选择python进行数据分析的理由和优势
  3. python怎么写文件-来看文件处理Python怎么写?
  4. JSR380(Bean Validation 2.0)
  5. qt中关闭窗口资源释放问题
  6. 网络编程学习笔记(Unix域套接口地址)
  7. 题目1206:字符串连接
  8. springAop源码分析
  9. C# 移除最后一个字符
  10. 慎重使用volatile关键字