百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

手把手教你用gdb调试mongod

nanshan 2024-11-23 20:14 14 浏览 0 评论

MongoDB作为一款NoSQL数据库,常应用在游戏开发领域。 作为一个后端程序,进行CRUD操作是家常便饭,但如果不看源码,便不会知道MongoDB底层是如何实现的,对自己写的CRUD代码,心里就没谱,不确定哪一行代码就把MongoDB给压垮了。遇到问题,不知道为啥MongoDB支撑不住,也就无从说起该怎样哪里优化。

开源MongoDB有上万个文件,代码量百万行。阅读MongoDB的源码是一项具有挑战的任务。一般的,我们可以从简单的、自己感兴趣的模块开始阅读。例如,先理解MongoDB在执行一条find命令时,是如何找到我们想要的结果。

本文,介绍如何编译MongoDB源码、如何用GDB调试MongoDB。

编译安装MongoDB

因为线上使用的是3.4.24版本,所以本文也采用该版本作为例子。

首先下载MongoDB源码

wget https://fastdl.mongodb.org/src/mongodb-src-r3.4.24.tar.gz

解压缩

tar -zxvf mongodb-src-r3.4.24.tar.gz 

在解压的目录中,docs/building.md介绍了如何编译安装MongoDB。

首先是安装依赖库

apt-get install aptitude
aptitude install scons build-essential
aptitude install libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-thread-dev

然后是通过scons命令进行MongoDB的编译安装。

scons core install --disable-warnings-as-errors

参数core,说明想要安装的包括mongod,mongos, mongo。加入参数--disable-warnings-as-errors是为了忽略编译过程的warning。

为了GDB能够调试MongoDB,需要在编译MongoDB时,加入-g参数。不然在调试时,会收到No symbol table is loaded的报错。通过查看SConstruct文件,已经加了-ggdb参数,所以我们就不需要做修改,直接执行scons就可以。



编译安装后,会在build/install/bin目录下,生成可执行文件:mongo,mongod,mongos,mongoperf

启用GDB调试

首先启动mongod。在build/install/bin目录下,执行 ./mongod启动mongod。

启动后,可以用ps -ef | grep mongod查看mongod的进程号,然后用ps -p 进程号 -T查看mongod创建的线程信息。

启动mongo。在build/install/bin目录下,执行./mongo启动mongo,使之直接连接mongod。

启动后,再次用ps -p 进程号 -T查看mongod创建的线程信息。这时,会发现多了一个conn1线程。这个线程,是mongod为一个客户端创建的。



在build/install/bin目录下,启动GDB,attach到mongod进程

gdb ./mongod 进程号

mongod是多线程,我们这里只关心处理客户端请求的线程。所以,先要切到相应的线程中。

使用info threads命令, 显示当前可调试的所有线程,每个线程会有一个GDB为其分配的ID,后面操作线程的时候会用到这个ID。 前面有*的是当前调试的线程



可以看到,处理客户端连接的线程,在GDB的编号是21,用thread 21切换到对应的线程中。

我们以find命令为例,介绍如何用GDB进行断点调试。

断点调试的第一步,就是加断点。这就需要找到find的入口在哪里,即在哪个文件的哪一行。 我们一般可以先快速过一遍mongod的源码结构。在src/mongo/db/commands发现了大量以命令命名的文件。通过简单分析我们有理由相信,find_cmd.cpp的run函数,就是find的入口。



确定了行号之后,就可以用gdb命令加断点了:

b src/mongo/db/commands/find_cmd.cpp:230

加好断点后,我们在启动的mongo进程中,触发find命令。

触发命令后,我们在gdb会话中,输入c告诉gdb继续执行,直到遇到我们设置的断点。



现在gdb已经定在了我们设置的断点中,下面可以利用gdb的其他命令,如命令s,n等,跟踪学习mongo的find命令实现了。

如果不幸的,我们没法通过源码发现find命令的入口,则只能借助gdb使用更暴力一些的办法。 在前文介绍的步骤中,当gdb关联到客户端的线程后,直接执行bt命令,看看现在的调用栈。



可以看到,线程在等待客户端数据,对应的文件是sock.cpp:692。



通过阅读源码,我们直接在sock.cpp:697加断点,客户端发起find请求,然后一步步调试,就能进入find的入口。


用docker编译调试mongod

编译安装mongod在不同的环境,会遇到各种奇葩的问题。我们为了用GDB调试mongod,可能会花大量时间在解决环境配置上。为了解决烦恼的环境问题,这里提供一个dockerfile,用docker可以完美的解决环境问题。

FROM debian:9
RUN apt-get install -y wget
RUN apt-get install -y vim
RUN apt-get install -y make
# 在Docker Debian容器中安装ps,top等命令
RUN apt-get install -y procps

RUN apt-get install -y gcc
RUN apt-get install -y g++

相关推荐

手机看视频卡顿的系统化解决方案(手机看视频特别卡是什么原因)

手机看视频卡顿是日常使用中常见的问题,通常由网络不稳定、设备性能不足、应用设置不当或系统问题导致。以下方案按优先级排序,兼顾操作难度与解决效果,帮助你快速定位并解决卡顿问题。一、网络优化:解决最核心诱...

电子电路硬件测试基础-板级测试工具之示波器(1)

示波器介绍示波器,作为一种电子测试仪器,主要用于对电信号的波形进行测量、显示与分析。它的工作原理是将电信号的瞬时值转化为屏幕上的垂直偏移,并以时间为基准在水平轴上展开,进而生成信号的图形化呈现。借助示...

宽带安装避坑指南:从选套餐到验收全流程注意事项

在网络成为生活必需品的当下,看似简单的宽带安装实则暗藏诸多细节,稍不留意就会踩入隐藏费用、性能虚标等陷阱。掌握以下关键要点,助你轻松避开宽带安装雷区。一、选对运营商与套餐,拒绝隐形消费选择运营商时,不...

噪声分析及小信号测试(噪音中的信号是什么含义)

示波器在大量开关电源或大功率用电器等复杂环境下进行自环测试,容易出现视频中的噪声问题。示波器在进行小信号测试时,我们要考虑地线带来的干扰,一般设置要求是:一、带宽限制打开;二、尽可能短的地线,一般使用...

怀疑房间被装了监控?深度解析检测方法与步骤

在现代社会中,隐私保护日益受到重视。当我们租房、住酒店或身处私人住宅时,如果发现房间内有异常的迹象,如电器无故自动开关、网络速度突然变慢、电费异常增加,或者在某些特定区域总感觉“被注视”,这些都可能是...

如何快速鉴定网线好坏?怎样测网线电阻?

一、快速鉴定网线好坏的3大核心技巧1.外观检测法:5秒看穿网线本质标识验证:正品网线外皮应清晰印有"CAT5e""CAT6"等类别标识,以及米数刻度(如30...

网速慢?教你快速检测网卡速率! #网络测速

网卡是百兆还是千兆?你知道吗?网速慢可能就是因为网卡不够快,今天就来教你如何快速检查网卡。1.打开CMD:首先找到电脑,按下Win+R键,输入cmd,然后按回车,这就打开了命令提示符...

怎么查自己家WiFi多少兆?(苹果手机测wifi网速)

怎么查自己家WiFi多少兆?在数字化生活日益普及的今天,家庭WiFi的速度直接影响着我们上网冲浪、在线学习、视频通话等日常活动的流畅度。了解自家WiFi的带宽通常以兆比特每秒Mbps为...

家里宽带网速不理想?测一下就知道了

家里网络不理想,经常发生卡顿或是网络抖动?可能是家里宽带的影响,这时候不妨实际测试下网速看看,是否符合预期。个人最近经历过两次上网卡顿问题,第一个是上个月回老家,刷剧的时候,发现有加载缓慢的情况,10...

Linux 必备的20个核心知识点(linux内核知识点)

学习和使用Linux所必备的20个核心知识点。这些知识点涵盖了从基础操作到系统管理和网络概念,是构建扎实Linux技能的基础。Linux必备的20个知识点1.Linux文件系统层级标...

忆享科技戟星安全实验室|内网隧道技术,你知道几个?

本文约6000字,阅读约需15分钟。0x00前言在实际环境中,会有各种网络设备、防火墙以及入侵检测系统阻止外网与内网的通信,我们构建内网隐蔽通道来突破安全策略的限制,实现对目标机器的控制。当我们在外...

Win10怎么连接linux虚拟机?(win10搭建linux虚拟机)

这个不难,主要是ping一下ip,检查win10系统是否和Linux虚拟机连通,接着开启ssh服务,如果一切正常的话,就可以连接linux虚拟机,这里简单介绍一下实现过程,实验环境win10+vmwa...

如何在CentOS中配置静态IP地址?(centos6.5配置静态ip地址)

静态IP地址是在计算机网络中使用的固定IP地址,与动态分配的IP地址相对。在CentOS中,通过配置网络设置,您可以轻松地为您的系统设置静态IP地址。本文将详细介绍在CentOS中配置静态IP地址的步...

Firewalld的简单使用(firewall direct)

从Centos7开始默认防火墙就已经更换为了firewall,替换了之前的iptablesFirewalld服务采用firewall-cmd或firewall-config(图形化工具)来动态管理ke...

Vmware设置静态IP和主机访问(vmware 设置固定ip)

摘要:Vmware设置静态IP和主机访问关键词:Vmware、静态IP、主机访问整体说明最近在做大模型的本地部署,发现之前的Virtualbox,不太能用到本地的英伟达GPU,所以开始使用...

取消回复欢迎 发表评论: