写给正在找工作的我们~~附上学习笔记

写在前面:
本人双非渣硕一枚,说起校招要从18年春招开始,在这之前,我有在百度和海康威视实习的经历,师兄们前几年工作都找的不错(阿里sp、网易sp、阿里),当时的我觉得春招信心满满,一定能找份不错的实习,然后尽早转正,解决工作问题!而事实是我想多了!先后投了阿里云、腾讯云、网易,阿里是最快面试的,第一次面阿里又是电话面试,之前都是现场的,有些不适应,面的时候太在乎、太紧张,好多简单的问题回答的很乱,没有一个明确的思路,有的问题没听清楚就回答了,导致答非所问,面试结果很显然,已回决,面完后想了下自己的面试过程,有的问题确实回答的太差了,心态调整了下,过了一天又来了腾讯的内推面试,这次面试比起阿里的准备的稍微充分点,面试到最后需要手写两道算法,我记得有一道二叉树翻转的题,我没写出来,很少写算法,不过面完感觉过程还不错,觉得能过,旁边的师兄一直听着也说面了50分钟,一面应该过了,我也觉得过了,结果一天后当前岗位不适合你,网易春招简历被刷,笔试被刷,双非的同学们想去网易笔试确实是一道大坎。经过这几次面试,当时我很绝望,一个星期晚上连续睡不着,脸色很差,那段时间,想给家人打电话,拿起手机又放下了,在外面,基本都是报喜不报忧的。。痛定思痛,好好总结了一下之前的面试,刷了leetcode、把自己的简历上一遍一遍的看,问自己是不是真熟悉了、了解了,每个项目是不是每一个点都get到了,经过一段时间调整,终于找到了美团补招的一份实习。不过学校暑期有中期比较晚,耽误了实习的时间,老师那边也不好讲,就没去实习,正式开始了校招的路,校招一路也磕磕绊绊,投了好多家没有音讯,只有少数几个公司有笔试、面试,到处跑宣讲会,终于在昨天收到了小米的offercall、美团的意向书。

tips:
心态一定要好,工作一定会有的,自己简历上写的一定要百分百很熟,面试要自信一点,尤其是一般学校的,越要自信,要听清楚面试官的问题,不要急着强答。手写算法是不可避免的,这个一定不要抱侥幸心理,多从面试官角度考虑他想要问什么点,电话面试环境要准备好,尽量带耳机,手里准备些笔和纸,可以写一写画一画。

写在最后
感谢牛客这个平台,感谢同实验室师兄们的帮助,感谢一路以来朋友们的支持,最后送一句话给正在找工作的同学们:人生不是百米赛跑,而是一场永无止境的马拉松。


附学习笔记(内核+网络+数据结构+算法+数据库):
知识点:
第一部分:数据结构
剑指offer:
二叉搜索树的第k个结点
对称的二叉树
二叉树的下一个结点
删除链表中重复的结点
判断二叉树是否平衡二叉树
二叉树的深度
两个链表的第一个公共结点
二叉树的镜像
合并两个排序的链表
反转链表
链表中倒数第k个结点
链表中间节点
快速排序法
归并排序法
链表是否相交
链表有无环
链表环的入口
二分查找
btree与二叉查找树
二叉树的遍历 递归 非递归 层序遍历
二分搜索树的增删改查
红黑树
hash hashmap map reduce
堆的实现
数组去重复元素
链表排序

第二部分:网络
网络概述:
1.数据包处理全过程
2.二层三层转发原理
3.二层三层网络功能
4.网络层包的问题
5.传输层怎么解决以上问题
6.应用层协议http dns ping traceroute rtp的过程
7.arp、rarp作用、使用场景、过程
8.路由协议bgp ospf rip

tcp协议:
1.ip数据包存在的问题?怎么解决?
2.tcp有哪些机制?校验和、序列号、确认机制、超时重传(默认1s)、窗口机制、流量控制、拥塞控制、连接管理
3.一个数据包大小怎么确定?mss在三次握手时确认?
4.延时确认机制(200ms)、nagle算法 、快速重传
5.拥塞控制的过程:慢启动算法、拥塞避免、快速重传、快速恢复
6.为什么tcp有首部长度而udp没有?
7.tcp包的长度怎么算?
8.什么叫字节流?什么叫数据报?tcp用哪种?
9.tcp字节流导致哪些问题?不实时、无边界可能会粘包?
10.粘包怎么解决?两种方法 总体来说,循环处理缓冲区的包,根据格式或头部长度来区分数据包
11.三次握手、四次挥手过程?状态?为什么是三次和四次?
12.发包后改变状态,收包后改变状态,应答不改变状态
13.三次握手中通过mss选项确定段的大小
14.挥手的6个状态?作用?fin_wait1 、fin_wait2半关闭状态、time_wait2msl时间close_wait、last_ack、closed
15.close_wait状态大量存在的原因?1.调用shutdown进行半关闭 2.程序忙于其他事情,没时间发fin包?
16.半打开连接,半关闭连接出现的情况?
17.同时打开、同时关闭的包及状态?
18.netstat命令查看tcp连接前后状态
19.数据包分为:交互数据流和块数据流 交互数据流:nagle算法、延时确认 块数据流:滑动窗口、窗口大小
20.push标志 、urg标志
15.短连接和长连接?

第三部分:内核
内存管理:1.内存的硬件访问原理及分页管理(mmu、页表、ZONE、Buddy、CMA)
2.内存的动态申请与释放(slab、kmalloc、vmalloc、malloc、Lazy分配机制、free)
3.进程的内存消耗与泄露(VMA、vss、uss、pss、rss、pagefault、OOM、内存泄露怎么检测以及处理)
4.内存与io的交换(page***、free命令、read/write/mmap、file-backed页面/匿名页、swap、LRU)
5.内存工程上的优化(DMA与***的一致性、进程的cgroup、内存的cgroup、dirty页的回收、内存的回收、swappniess、getdelays、vmstat工具)

一.内存的硬件访问原理及分页管理(mmu、页表、ZONE、Buddy、CMA)
1.cpu如何访问到内存?
2.mmu的作用?
3.页表的内容?
4.物理内存分为几个zone?为什么要分zone?
5.什么是buddy算法?buddy算法有哪些问题?怎么查看buddy管理的物理内存资源?
6.什么是CMA算法?
7.内存是按页管理的,文件系统是按block管理的,buddy算法适用于每个zone,用于管理空闲页面,zone是物理内存的概念。
8.为什么要分用户空间和内核空间?
9.进程只需要虚拟地址连续,物理地址连不连续无所谓,但DMA对连续有要求。

二.内存的动态申请与释放(slab、kmalloc、vmalloc、malloc、free、Lazy分配机制、OOM)
1.slab是什么?为什么要有slab?和buddy什么关系?malloc与buddy的关系?怎么查看slab为内核提前分配的内存?举例子
2.kmalloc、vmalloc、malloc的区别?页表什么时候建立?从哪个zone拿内存?分别映射到哪里?vmalloc映射区的作用?怎么看vmalloc映射区?
3.lazy行为是什么?适用于哪些场景?为什么要有lazy?lazy不止针对于应用的堆,还包括代码段、数据段等。
4.什么是OOM?出现OOM,内核怎么处理?怎么查看进程的oom_score?
5.mallopt函数作用?
6.映射讲的是建立页表关系,占用讲的是内存命中。
7.malloc基于brk、mmap系统调用。

三.进程的内存消耗与泄露(VMA、vss、uss、pss、rss、pagefault、内存泄露怎么检测以及处理)
1.进程的VMA是什么?
2.一个进程究竟消耗了多少内存?vss、rss、uss、pss?怎么查看?pmap pid cat /proc/pid/maps or smaps smem
3.malloc成功后并未拿到内存(lazy行为),但对进程产生了什么影响?VMA+页表
4.一个进程的内存消耗从来不说进程在内核空间的消耗,而是在虚拟地址空间0-3g对应的物理内存的那部分消耗。
5.内存如何被多个进程瓜分?图?
6.pagefault(缺页中断)的三种可能性?major与minor的区别?
7.应用内存泄露的原因?界定方法?位置的检测方法?

四.内存与io的交换(page***、free命令、read/write/mmap、file-backed页面/匿名页、swap、LRU)
1.lazy行为不仅仅针对堆,代码段、栈等都是边写边pagefault,边写边拿到。
2.什么是file-backed页面?什么是匿名页?如何在内存与磁盘间交换?
3.swap什么意思?什么是硬盘的swap分区?
4.应用程序读写文件的两种方法?区别?过程?read/write/mmap
5.什么是page***,有什么用?page***两种形式?buffers ***d
6.free命令的作用?每一项含义?
7.LRU?最近最少使用原则
8.嵌入式下不使用swap分区的原因?使用ZRAM的原理?牺牲了什么?
9.内核2号进程kthreadd进程负责文件系统的页面以及匿名页面的回收,每个zone有3个水位,high、low、min水位,当空闲内存大于high水位时,停止回收,当处于high水位和low水位之间时后台开始慢慢回收,当低于min水位时,内核会堵住应用程序,快速内存回收。
10.cat/proc/sys/vm/swappiness swappiness 反应是否积极的使用swap空间

五.内存工程上的优化(DMA与***的一致性、进程的cgroup、内存的cgroup、dirty页的回收、内存的回收、swappniess、getdelays、vmstat工具)
1.DMA与***的一致性指什么?怎么解决?DMA_alloc_coherent()分配,***的硬件同步单元
2.进程的cgroup作用?配置group的优先级、cpu的最大占用率过程
3.内存的cgroup作用?配置group的swappniess、最大内存消耗过程
4.dirty页为什么要写回?怎么写回?时间:dirty_expire_centisecs 默认30s,线程周期性(dirty_writeback_centisecs)起来回写,空间上按比例:dirty_background_ratio,dirty_ratio
5.内存回收的3个水位及回收过程?
6.vmstat工具:分析硬盘压力、swap压力、写文件压力等
7.getdalays工具:评估程序的等待cpu、mem、swap、io的时间,可以知道程序哪慢

进程线程管理以及调度:
1.进程是什么?有哪些资源?pidmax怎么查?
2.task_struct如何被管理?分别适合哪些场景?
3.进程的生命周期图?6态之间的关系?
4.什么是内存泄漏?进程活着才有内存泄漏
5.作业控制的命令?ctrl z bg fg cpulimit作用?原理?
6.fork例子中printf打印几次?fork后进程处于就绪态
7.什么是僵尸进程?怎么处理?可以设置sigchld的函数为默认,由init去收尸
8.&、killall、pstree
9.fork、vfork、pthread_create怎么实现?
10.写时拷贝怎么实现?例子
11.进程0进程1的作用
12.睡眠和等待队列的实现?
13.什么是孤儿进程?怎么托孤?subreaper
14.top -H
15.两组矛盾:吞吐vs响应   io消耗型vscpu消耗型 arm big-Little架构cpu
16.调度策略:实时进程 sched_rr sched_fifo普通进程 nice值 +-5的奖励 cfs完全公平调度
17任务频繁切换导致哪些问题?
18.nice低的好处?默认为0
19.nice renice chrt
20.多核时的负载均衡分rt进程和普通进程,rt进程平分到各个核上,普通进程周期性负载均衡,fork时负载均衡

文件系统:
一.应用程序发起io行为,最终怎么走到硬盘?
1.应用程序首先和page***打交道
2.page***和硬盘打交道(真正去做io行为,称为block io子系统)
二.free命令下buffer和***d的区别?
三.O_DIRECT和O_SYNC的区别?
四.IO电梯调度器的策略?deadline、cfs、noop
五.块设备的读写过程及性能怎么分析(哪个地方比较慢)?ftrace、blktrace的作用?怎么使用?
1.blktrace -d /dev/sda1 -o - |blkparse -i - >1.trace
2.ftrace跟踪块设备读写时的函数及执行时间,函数级别的,而blktrace是针对io的流程,什么时候进plug,什么时候进io调度器等。
六.ionice、iotop、iostat
ionice -c 2 -n 0 cat /dev/sda > /dev/null&
ionice -c 2 -n 7 cat /dev/sda > /dev/null&
iotop
iostat

1.EXT系列文件系统布局以group为单位?(/a/b b在硬盘上如何存放的?)
2.append一个文件的全流程(删除一个文件的流程)
3.掉电会导致哪两种问题?分别举例子!为什么会出现不一致?
4.怎么保证文件系统的一致性?fsck 日志
5.修改文件系统,造成文件系统不一致?现象,怎么解决?
6.fsck原理?
7.日志怎么保证文件系统一致性?
8.EXT4文件系统工具:mkfs、dumpe2fs、
blkcat、dd、debugfs blktrace

1.vfs和文件系统的关系?
2.文件系统是如何组织起来的?
3.vfs的数据结构有哪些?作用?
4.目录是什么?怎么访问/usr/bin/emaxs
5.软链接和硬链接区别?怎么创建ln aa bb,ln -s  cc bb
6.应用程序read到vfs到page***到读写硬盘的***作过程?
7.dmesg两个作用 内核启动信息 prink打印的信息
dmesg -c  dmesg  > 文件
8.simplefs怎么做的,有哪些数据结构,流程是什么?

IO模型:
1.阻塞io可以被信号打断以及阻塞io的实现
2.网络模型包括:一个连接,一个进程或线程、一个进程或线程处理多个连接(select/epoll)优缺点及实现方式
3.signal io及aio的实现
4.epoll+任务队列+线程池的实现代码(互斥锁和条件变量的使用)
5.epoll的事件类型:EPOLLIN、EPOLLOUT、EPOLLET、EPOLLLT
6.条件变量的唤醒:phread-cond-singal、phread-cond-broadcast 区别

1.为什么有那么多种io模型?
2.5种io模型的特点,怎么使用?
3.vfs是什么,什么作用?有哪些数据结构?
4.硬盘是如何组织成文件系统的,文件系统是怎么样的架构?
5.软链接硬链接区别?
6.读取/usr/bin/xxx的全流程
7.ext2/3/4的布局格式
8.从上到下发起一次block io的全流程

第四部分:数据库
数据库:
1.mysql的使用?show database;use mysql;show tables;describe xxx;select delete update insert xxx;
2.什么是数据库事务?事务的属性?
事务指单个逻辑单元执行的一系列的***作,要么都执行,要么都不执行。
一个逻辑单元要成为事务,必须满足ACID的属性,即原子性、连续性、隔离性、持久性
原子性:一件事情会有多个***作,必须都执行或都不执行。
一致性:数据库的数据要在事务前后保持一致。
隔离性:对同一个表并发进行多个事务,事务间相互隔离。
持久性:一旦事情commit,不可更改,持久生效。
3.数据库底层存储结构?btree、b+tree
3.1BST、AVL树、RBtree、btree、b+tree的定义、图样?
3.2BST、AVL树、RBtree都是二叉搜索树,AVL树、RBtree增加了平衡树的特点。
3.3BST  1.vs二分查找,BST在左右子树节点个数差不多时,查找性能逼近二分查找,但在增删节点时,BST需要的内存比二分查找少。2.缺点:平衡性差,动态增删节点可能导致退化为链表,查找效率降低。
3.4AVL树vsRBtree: avl树是严格平衡树,而rbtree是弱平衡树,都是通过旋转来保持平衡,而在增删节点时,严格平衡树旋转的次数比弱平衡旋转的次数多,当搜索节点的次数远远大于增删节点的次数时,旋转AVL树,当搜索节点的次数与增删节点的次数差不多时选择RBtree效率高。
3.5磁盘读取及预读的过程及时间消耗?定位柱面时间(最长)、旋转至扇区时间、读写扇区时间
3.6为什么btree查找效率高?多路查找-->降低树的高度-->减少磁盘io的次数-->节省磁盘访问的时间-->更快定位到数据库文件
3.7btree节点如何定义?vs二叉搜索树 二叉搜索树:key、value、left指针、right指针  btree节点:多个key key1 key2..多个value value1 value2..多个pointer指针 pointer1、pointer2..
3.8btree定义?1.每个节点最多有n个子树
2.根节点至少有两个子树
3.分支节点至少拥有m/2棵子树(除根和叶子)
4.所有叶子节点都在同一层,每个节点最多可以有m-1个key并且升序排列
相同数量的key在btree中生成的节点要远远小于二叉搜索树节点,相差的节点数目正比于树的高度正比与磁盘io的次数,达到一定数量时,性能差异明显。
3.9 b+tree 叶子节点包含了所有关键字信息以及指向这些关键字记录的指针,并且叶子节点大小本身就是从小到大的顺序链接。
3.10为什么b+tree比btree更适合做文件的索引、数据库索引?
1.btree在提高磁盘io性能同时并没有解决元素遍历效率低下的问题,b+tree只要遍历叶子节点就可遍历整棵树。
2.在数据库中基于范围的查找很频繁,btree每次都要从根节点查,效率低。b+tree可以直接去访问叶子节点,找到相应的范围。

第五部分:调试
GDB调试:
GDB主要帮忙你完成下面四个方面的功能:
1.启动你的程序,可以按照你的定制要求随心所欲的运行程序。
2.可让被调试的程序在你所指定的调置的断点处停住。
3.当程序被停住时,可以检查此时你的程序中所发生的事,以及内存状态等。
4.动态的改变你程序的执行环境。

第一部分:如何使用gdb?
a.单步 next/n
b.断点 break/b、info breakpoints、delete breakpoints 1
c.watchpoint 观察某个变量或内存地址的状态 watch i、info watchpoints、delete breakpoints 1
d.看变量,改变量 print/p xxx、set var i=0
e.看内存,改内存 print &i 、x /nfu xx n为显示内存单元的个数 f表示显示格式 u表示一个地址单元长度
f.backtrace 当程序停住,通过bt查看代码在哪停住了
g.gdb的TUI模式,多窗口视角
调试代码的时候,只能看到下一行,每次使用list非常烦,不知道当前代码的context
Ctrl+x+a 进入或退出TUI(终端用户界面)


第二部分:gdb的实现原理
在使用gdb调试程序时,程序的进程状态是”T”,t (TASK_TRACED),进程被追踪状态。
gdb依赖系统调用ptrace,ptrace可以让父进程观察和控制子进程的执行、改变寄存器和内存的内容。1.gdb调试一个新进程:通过fork函数创建一个新进程,在子进程中执行ptrace(PTRACE_TRACEME, 0, 0, 0)函数,然后通过execv()调用准备调试的程序。PTRACE_TRACEME表示本进程将被其父进程跟踪,交付给这个进程的所有信号(除SIGKILL之外),都将使其停止,父进程将通过wait()获知这一情况。
2.运行gdb,输入attach pid,attach到已运行进程:将pid传递给gdb,然后执行ptrace(PTRACE_ATTACH, pid, 0, 0)。PTRACE_ATTACH attach到一个指定的进程,使其成为当前进程跟踪的子进程,子进程的行为等同于它进行了一次PTRACE_TRACEME***作。
断点的原理;
1)断点的实现原理,就是在指定的位置插入断点指令,当被调试的程序运行到断点的时候,产生SIGTRAP信号。该信号被gdb捕获并进行断点命中判定,当gdb判断出这次SIGTRAP是断点命中之后就会转入等待用户输入进行下一步处理,否则继续。父进程发SIGSTOP信号暂停子进程。
2)断点的设置原理: 在程序中设置断点,就是先将该位置的原来的指令保存,然后向该位置写入int 3。当执行到int 3的时候,发生软中断,内核会给子进程发出SIGTRAP信号,当然这个信号会被转发给父进程。然后用保存的指令替换int3,等待恢复运行。
3)断点命中判定:gdb把所有的断点位置都存放在一个链表中,命中判定即把被调试程序当前停止的位置和链表中的断点位置进行比较,看是断点产生的信号,还是无关信号。
单步的原理:
ptrace本身支持单步功能,调用ptrace(PTRACE_SINGLESTEP,pid,...)即可
单步分为:指令级别单步(step)和c代码级单步(next),指令级单步分为硬件单步和软件单步,硬件单步指目标程序执行一条指令后自动停止,而软件单步指用临时的软件断点来模拟单步,插入断点、命中断点、删除断点。

第三部分:gdb调试案例
a.调试一个应用(多线程)
a.1调试一个未运行的单线程应用
反转字符串:1.设置断点、观察点
2.单步运行,查看变量发现size问题
a.2调试一个未运行的多进程应用
1.查看系统默认的follow-fork-mode 和 detach-on-fork:show follow-fork-mode、
show detach-on-fork
follow-fork-mode detach-on-fork 说明:
parent                   on               只调试主进程(GDB默认)
child                      on               只调试子进程
parent                   off              同时调试两个进程,gdb跟主进程,子进程block在fork位置
child                      off              同时调试两个进程,gdb跟子进程,主进程block在fork位置
2.设置follow-fork-mode 和 detach-on-fork:set follow-fork-mode [parent|child]   set detach-        on-fork [on|off]
3.用l/list命令查看源代码(按enter翻页),分别在子进程和父进程相应位置下断点:b 17 、b 21
4.运行程序,查询正在调试的进程:显示GDB调试的所有inferior,GDB会为他们分配ID。其中带有*的进程是正在调试的inferior。(GDB将每一个被调试程序的执行状态记录在一个名为inferior的结构中,一般情况下一个inferior对应一个进程,每个不同的inferior有不同的地址空间。inferior有时候会在进程没有启动的时候就存在。)
run
info inferiors
5.切换调试的进程:inferior <infer number>
a.3调试一个未运行的多线程应用
1.info threads显示可以调试的所有线程。gdb会为每个线程分配一个ID(和tid不同),编号一般从1开始。
2.在主线程处打断点、在线程1中打断点 、在线程2中打断点
3.thread ID 切换当前调试的线程为指定ID的线程。
a.4调试一个已经运行的应用
attach pid
a.5调试一个hang的应用: 两个线程死锁 info threads、thread i、bt、print
b.调试内核源码
Linux系统启动,从start_kernel开始执行,中间执行一系列的初始化动作,为后面系统启动开始运行作准备。start_kernel函数的最后会调用rest_init,  然后在rest_init里创建一个进程去寻找文件系统中init程序并执行,这个就是系统的1号进程。1,2号进程后,系统会进入cpu_idle_loop()死循环,这个就是原始的启动进程,也就是0号进程;当系统没有进程需要执行的时候,就会调用这个idle进程
执行下面的命令即可开始跟踪查看Linux启动过程:
1. qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img -s -S # 关于-s和-S选项的说明:
2. # -S freeze CPU at startup (use ’c’ to start execution)
3. # -s shorthand for -gdb tcp::1234 若不想使用1234端口,则可以使用-gdb tcp:xxxx来取代-s选项
另开一个shell窗口
1. gdb
2. (gdb)file linux-3.18.6/vmlinux # 在gdb界面中targe remote之前加载符号表
3. (gdb)target remote:1234 # 建立gdb和gdbserver之间的连接,按c 让qemu上的Linux继续运行
4. (gdb)break start_kernel # 断点的设置可以在target remote之前,也可以在之后


gdb常用命令大全:
gcc -g  main.c                      //在目标文件加入源代码的信息
gdb a.out
(gdb) start                         //开始调试
(gdb) n                             //一条一条执行
(gdb) step/s                        //执行下一条,如果函数进入函数
(gdb) backtrace/bt                  //查看函数调用栈帧
(gdb) info/i locals                 //查看当前栈帧局部变量
(gdb) frame/f                       //选择栈帧,再查看局部变量
(gdb) print/p                       //打印变量的值
(gdb) finish                        //运行到当前函数返回
(gdb) set var sum=0                 //修改变量值
(gdb) list/l 5 行号或函数名             //列出源码,以第5行为中心显示
(gdb) display/undisplay sum         //每次停下显示变量的值/取消跟踪
(gdb) break/b  行号或函数名           //设置断点
(gdb) continue/c                    //连续运行
(gdb) info/i breakpoints            //查看已经设置的断点
(gdb) delete breakpoints 2          //删除某个断点
(gdb) disable/enable breakpoints 3  //禁用/启用某个断点
(gdb) break 9 if sum != 0           //满足条件才激活断点
(gdb) run/r                         //重新从程序开头连续执行+
(gdb) watch input[4]                //设置观察点
(gdb) info/i watchpoints            //查看设置的观察点
(gdb) x/7b input                    //打印存储器内容,b--每个字节一组,7--7组
(gdb) disassemble                   //反汇编当前函数或指定函数
(gdb) si                            // 一条指令一条指令调试 而 s 是一行一行代码
(gdb) info registers                // 显示所有寄存器的当前值
(gdb) x /nfu 内存地址                   //查看内存
(gdb)ptype i                   //查看变量i的内型
(gdb)where                  //查看当前程序的位置

内核调试:
1.printk怎么实现?怎么用?怎么查看printk的内容?dmesg -c、dev_xxx、ptr__xxx、initcall_debug、查看打印级别 cat /proc/sys/kernel/printk
printk依赖于uart驱动子系统,在这之前使用early_printk打印
initcall_debug定位linux开机hang死问题,linux启动时调用很多init_function(各个模块的init在哪?)
2.gdb的实现?怎么使用?调试应用、内核源码、内核模块的过程?调试的代码如何和窗口一起显示?
3.用gdb对内核进行源代码级别的调试(使用qemu在没有电路板的情况下进行内核源代码级别的调试)
qemu软件用于模拟硬件设备
qemu -S-s启动,gdb target ip连接,b打断点,c执行,n单步
4.用gdb对内核模块进行源代码级别的调试
不知道模块的代码段和数据段,需要告诉gdb,cd /sys/module/globalmem/sections,cat .text,cat .data
gdb add-symbol-file globalmem.ko xxx地址
5.内核崩溃如何定位到哪一行汇编代码?如何看oops和panic,oops和panic的区别,内核反汇编方法?
oops包含出错原因、出错的文件、函数、代码偏移、backtrace+反汇编objdump .o文件=》定位代码
制作oops,并利用oops信息和objdump定位代码(驱动中经常oops)
oops不一定内核崩溃,如果oops在进程上下文,杀掉进程,若在中断上下文,直接panic
panic指内核崩溃
panic_on_oops设置为1,一律panic
例子:制造gloablmem驱动read中访问空指针,cat /device/gloablmem 引起oops,通过oops+objdump定位,内核出错的位置
6.内核内存泄露、内存越界的调试?应用程序内存泄露怎么调试呢?kmemleak怎么实现?
案例:分析是否有内存泄露的过程?有内存泄露怎么处理?
例子:制造gloablmem驱动read中内存的泄露,多次释放等问题,cat /device/gloablmem引起内存泄露,cat /sys/kernel/debug/kmemleak记录可能泄露的地方
例子:制造gloablmem驱动read中多次释放、越界等问题,一旦cat /device/gloablmem引起内存多次释放和越界 slubdebug出错的信息 slabinfo -v打印出错的信息


#笔记#
全部评论
给大神点赞
点赞
送花
回复
分享
发布于 2018-09-26 14:35
点赞
送花
回复
分享
发布于 2018-09-26 14:38
滴滴
校招火热招聘中
官网直投
楼主很棒
点赞
送花
回复
分享
发布于 2018-09-26 14:50
马克🐴
点赞
送花
回复
分享
发布于 2018-09-26 17:40
顶一下
点赞
送花
回复
分享
发布于 2018-10-03 10:54

相关推荐

28 160 评论
分享
牛客网
牛客企业服务