在Linux系统中,Debug文件是一种十分重要的文件类型,它包含了程序运行时的调试信息,可以帮助程序员分析、定位程序的错误。在调试过程中,Debug文件是必不可少的,因为它能够提供程序在运行时的程序计数器、栈跟踪、函数参数、变量、源代码等信息,从而帮助程序员找到问题的具体所在。本文将详细介绍Linux Debug文件的相关知识和使用方法。
公司主营业务:网站设计制作、网站设计、移动网站开发等业务。帮助企业客户真正实现互联网宣传,提高企业的竞争能力。成都创新互联是一支青春激扬、勤奋敬业、活力青春激扬、勤奋敬业、活力澎湃、和谐高效的团队。公司秉承以“开放、自由、严谨、自律”为核心的企业文化,感谢他们对我们的高要求,感谢他们从不同领域给我们带来的挑战,让我们激情的团队有机会用头脑与智慧不断的给客户带来惊喜。成都创新互联推出兴平免费做网站回馈大家。
一、产生Debug文件的方式
在Linux系统中,Debug文件是通过编译器和链接器来生成的。编译器的作用是将源代码转化为机器代码,而链接器则将编译器生成的目标文件、库文件等链接在一起,形成可执行文件。Debug文件的生成是编译器和链接器在编译和链接过程中的一部分工作,它们会将代码中一些符号的地址信息等调试信息存储在Debug文件中。
编译器和链接器都支持生成Debug文件的选项,具体方法如下:
1.使用GCC编译器
在使用GCC编译器时,使用-g选项可以指定生成Debug文件,例如:
“`
gcc -g test.c -o test
“`
这条命令会将test.c文件编译成目标文件test.o,然后将test.o链接成可执行文件test,并在该过程中生成Debug文件test.debug。
2.使用GDB调试器
GDB是Linux系统中更流行的调试器之一,它可以使用以下命令生成Debug文件:
“`
gdb -batch -ex ‘compile -g test.c’ -ex ‘quit’
“`
这条命令会将test.c编译成目标文件test.o,并在该过程中生成Debug文件test.debug,但不会链接生成可执行文件。
二、Debug文件的格式
在Linux系统中,Debug文件有多种格式,包括ELF格式、DWARF格式、STABS格式等。其中,DWARF(Debugging With Attributed Record Formats)格式是Linux系统中最常用的Debug文件格式,支持多种调试信息,包括源代码信息、变量信息、函数调用关系、类型信息等。DWARF格式的Debug文件通常以.dwo或.debug文件名后缀结尾。
三、Debug文件的使用
Debug文件主要用于程序调试,通过Debug文件可以获取程序运行时的相关信息,如变量值、函数调用关系、栈跟踪、源代码等。以下列举几个使用Debug文件调试程序的方法:
1.使用GDB调试器
GDB是Linux系统中最常用的调试器,可以通过以下命令将Debug文件加载到GDB中:
“`
gdb test
(gdb) symbol-file test.debug
“`
这样就将Debug文件加载到了GDB中,在调试过程中可以查看各种调试信息。
2.使用Eclipse IDE
Eclipse是一款强大的开发工具,它集成了各种开发工具,包括调试工具。可以通过以下步骤使用Debug文件来调试程序:
(1)在Eclipse中打开程序项目;
(2)通过“Debug Configurations”菜单进入调试设置界面;
(3)在“C/C++ Application”窗口中选择要调试的程序;
(4)在“Debugger”选项卡中选择GDB调试器;
(5)在“Debugger”选项卡中设置Debug文件路径。
这样就可以在Eclipse IDE中使用Debug文件来调试程序了。
3.使用Valgrind工具
Valgrind是一款程序分析和调试工具,它可以检查程序中的内存泄漏、越界访问等问题,使用非常方便。可以通过以下步骤使用Debug文件来调试程序:
(1)用-g选项重新编译程序文件;
(2)使用valgrind命令行工具启动程序;
(3)在valgrind中执行需要调试的程序。
四、Debug文件的注意点
在使用Debug文件调试程序时,需要注意以下几点:
1.要保证Debug文件所在路径和程序文件所在路径相同,否则GDB等调试器可能无法找到Debug文件。
2.要注意Debug文件的大小,Debug文件通常比较大,可能会占用较多磁盘空间,需要及时清理。
3.要保证Debug文件的安全性,Debug文件中包含了程序运行时的重要信息,可能会被黑客利用,需要妥善保管。
Debug文件是程序调试中不可或缺的一环,它提供了程序在运行时的各种调试信息,能够帮助程序员找到程序的错误所在。本文介绍了Debug文件的产生方式、格式、使用方法和注意点,希望能够帮助读者更好地理解和使用Debug文件。
相关问题拓展阅读:
1. sar
每两秒刷新一次, 总共5次
# sar 2 5
Linux 2.6.32-504.el6.x86_64 (dbhost01) 03/30/2023 _x86_64_ (4 CPU)
02:53:15 PM CPU %user %nice %system %iowait %steal %idle
02:53:17 PM all……96
02:53:19 PM all……51
02:53:21 PM all……17
02:53:23 PM all……80
02:53:25 PM all……70
Average:all……23
2. top
top -a 按照拿亩码内耐瞎存降消哪序
# top -a
top – 15:00:54 up 6:04, 1 user, load average: 0.31, 0.19, 0.11
Tasks: 306 total, 1 running, 305 sleeping, 0 stopped, 0 zombie
Cpu(s): 7.8%us, 2.4%sy, 0.0%ni, 88.9%id, 0.8%wa, 0.0%hi, 0.1%si, 0.0%st
Mem:k total,k used,k free,k buffers
Swap:k total,k used,k free,k cached
3. vmstat
vmstat用于显示虚拟内存,内核线程,磁盘,系统进程, CPU活动等统计信息。
需要安装sysstat工具。
# vmstat
procemoryswapiosystemcpu—–
r b swpd free buff cache si so bi bo in cs us sy id wa st
#
# vmstat 2 5
procemoryswapiosystemcpu—–
r b swpd free buff cache si so bi bo in cs us sy id wa st
4. lsof(list open files)
# lsof | grep 1521
certmongeroot 16r FIFO 0,tpipe
certmongeroot 18r FIFO 0,tpipe
gipcd.bingrid 109u unix 0xffff 0tsocket
5. tcpdump
tcpdump -i eth1
15:24:28.IP dbhost01.ssh > 192.168.2.82.50990: Flags
, seq:393596, ack 105, win 148, options , length 516
15:24:28.IP dbhost01.ssh > 192.168.2.82.50990: Flags
, seq:393596, ack 105, win 148, options , length 516
15:24:28.IP dbhost01.ssh > 192.168.2.82.50990: Flags
, seq:393968, ack 105, win 148, options , length 372
15:24:28.IP dbhost01.ssh > 192.168.2.82.50990: Flags
, seq:393968, ack 105, win 148, options , length 372
15:24:28.IP 192.168.2.82.50990 > dbhost01.ssh: Flags , ack, win 16652, options , length 0
15:24:28.IP dbhost02-priv.23602 > dbhost01-priv.24271: UDP, length 556
15:24:28.IP dbhost01-priv.24271 > dbhost02-priv.23602: UDP, length 80
15:24:28.IP dbhost01-priv.24271 > dbhost02-priv.23602: UDP, length 80
15:24:28.IP dbhost01.ssh > 192.168.2.82.50990: Flags
, seq:394724, ack 105, win 148, options , length 756
15:24:28.IP dbhost01.ssh > 192.168.2.82.50990: Flags
, seq:394724, ack 105, win 148, options , length 756
15:24:28.IP dbhost01-priv.24271 > dbhost02-priv.23602: UDP, length 556
15:24:28.IP dbhost01.ssh > 192.168.2.82.50990: Flags
, seq:395176, ack 105, win 148, options , length 452
15:24:28.IP dbhost01.ssh > 192.168.2.82.50990: Flags
, seq:395176, ack 105, win 148, options , length 452
6.netstat
# netstat -a | grep oracle
unix STREAM LISTENING/var/tmp/.oracle/ora_gipc_sdbhost01gridmyracdb-clusterCRFM_SIPC
unix STREAM LISTENING/var/tmp/.oracle/sdbhost01DBG_LOGD
unix STREAM LISTENING/var/tmp/.oracle/sdbhost01DBG_EVMD
unix STREAM LISTENING/var/tmp/.oracle/sAevm
unix STREAM LISTENING/var/tmp/.oracle/sSYSTEM.evm.acceptor.auth
7. htop
需要安装
8. iostat
Total DISK READ: 91.48 K/s | Total DISK WRITE: 45.27 K/s
TID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
4071 be/4 oracle.18 K/s 0.00 B/s 0.00 % 4.69 % ora_lmon_orcl1
4117 be/4 oracle.36 K/s 15.09 K/s 0.00 % 3.69 % ora_ckpt_orcl1
2989 rt/4 grid.71 B/s 0.00 B/s 0.00 % 2.13 % ocssd.bin
4099 be/4 oracle.00 B/s 30.18 K/s 0.00 % 0.07 % ora_ckpt_test
2987 rt/4 grid.00 B/s 482.86 B/s 0.00 % 0.03 % ocssd.bin
2979 rt/3 root.00 B/s 3.77 K/s 0.00 % 0.00 % ologgerd -M -d /g01/grid/app/11.2.0/grid/crf/db/dbhost01
2980 rt/3 root.00 B/s 15.09 K/s 0.00 % 0.00 % ologgerd -M -d /g01/grid/app/11.2.0/grid/crf/db/dbhost01
static int __init ohci_hcd_mod_init(void)
{
platform_driver_register(&ohci_hcd_s3c2410_driver);
}
其实真正注册的是ohci_hcd_s3c2410_driver这个驱动。那我们来看一下这个结构体的具体值。
static struct platform_driver ohci_hcd_s3c2410_driver= {
.probe = ohci_hcd_s3c2410_drv_probe,
.remove = ohci_hcd_s3c2410_drv_remove,
.shutdown = u_hcd_platform_shutdown,
.driver = {
.owner = THIS_MODULE,
.name = “s3c2410-ohci”,
},
};
那我们一一来看上述的每一个函清知数的实现。
2.1 hcd 探测
函数很简单其实现功能的是u_hcd_s3c2410_probe函数。
static int ohci_hcd_s3c2410_drv_probe(structplatform_device *pdev)
{
returnu_hcd_s3c2410_probe(&ohci_s3c2410_hc_driver, pdev);
}
ohci_s3c2410_hc_driver提供了对于ohci的操作集。对于这些函数在后面的学习中去看,在此不加扩展。我们将下面的函数剔除枝叶留其主干。
static int u_hcd_s3c2410_probe (const structhc_driver *driver,
struct platform_device *dev)
{
structu_hcd *hcd = NULL;
int retval;
#if !defined(CONFIG_ARCH_2410)
u_host_clk_en();使能clk
#endif
s3c2410_u_set_power(dev->dev.platform_data,1, 1);
s3c2410_u_set_power(dev->dev.platform_data,2, 1);
hcd =u_create_hcd(driver, &dev->dev, “s3c24xx”); –创建一个hcd
hcd->rsrc_start= dev->resource.start; –获取物理地址
hcd->rsrc_len = dev->resource.end -dev->resource.start + 1;
request_mem_region(hcd->rsrc_start,hcd->rsrc_len, hcd_name);
clk =clk_get(&dev->dev, “u-host”);
s3c2410_start_hc(dev,hcd);
hcd->regs= ioremap(hcd->rsrc_start, hcd->rsrc_len);
ohci_hcd_init(hcd_to_ohci(hcd));
retval = u_add_hcd(hcd,dev->resource.start, IRQF_DISABLED);
return 0;
}
对于u的电源管理,我们暂时不看,不看不代表不重要,电源管理是很重枯仔要的。
那依次来看上面的函数。答败消u_create_hcd创建和初始化一个hcd结构体。
s3c2410_start_hc启动hc。这里有一个很奇怪的结构体就是struct s3c2410_hcd_info,在s3c6410中并没有看到该结构体的赋值。也许有人对此很困惑,该结构体做什么用的。那我们来看该结构体的真正面目。
struct s3c2410_hcd_info {
structu_hcd *hcd; –保存该hcd_info所属的hcd
structs3c2410_hcd_portport; –两个端口。
void(*power_control)(intport, int to); –电源控制
void(*enable_oc)(structs3c2410_hcd_info *, int on);
void(*report_oc)(structs3c2410_hcd_info *, int ports);
};
在u-host.txt中对其功能进行了说明,就是一对函数,使能过流检测和控制端口电源状态。
power_control:使能或禁止端口电源
enable_oc :使能或禁止端口过流检测
report_oc :当端口存在过流,则会调用该函数。
static void s3c2410_start_hc(structplatform_device *dev, struct u_hcd *hcd)
{
structs3c2410_hcd_info *info = dev->dev.platform_data;
clk_enable(clk);
if (info !=NULL) { –在s3c6410中该info为空。
info->hcd = hcd;
info->report_oc= s3c2410_hcd_oc;
if(info->enable_oc != NULL) {
(info->enable_oc)(info,1);
}
}
}
初始化ohci_hcd
static void ohci_hcd_init(structohci_hcd *ohci)
{
ohci->next_statechange= jiffies;
spin_lock_init(&ohci->lock);
INIT_LIST_HEAD(&ohci->pending);
}
初始化并注册u_hcd
完成通用hcd的初始化和注册,在这里同时完成中断的申请和注册。
int u_add_hcd(struct u_hcd *hcd,unsigned intirqnum, unsigned long irqflags)
{
int retval;
structu_device *rhdev;
hcd->authorized_default= hcd->wireless? 0 : 1; –判断是否为无线
set_bit(HCD_FLAG_HW_ACCESSIBLE,&hcd->flags); –设置HW_ACCESSIBLE旗标
if ((retval =hcd_buffer_create(hcd)) != 0) { –开辟hcd的缓冲区
returnretval;
}
if ((retval =u_register_bus(&hcd->self)) self, 0)) == NULL) {
retval= -ENOMEM;
gotoerr_allocate_root_hub;
}
rhdev->speed= (hcd->driver->flags & HCD_USB2) ? USB_SPEED_HIGH :USB_SPEED_FULL;–指定根hub的speed
hcd->self.root_hub= rhdev;
device_init_wakeup(&rhdev->dev,1);
if(hcd->driver->reset && (retval = hcd->driver->reset(hcd))self.controller)
&&device_can_wakeup(&hcd->self.root_hub->dev))
dev_dbg(hcd->self.controller,”supports USB remote wakeup\n”);
if(hcd->driver->irq) { –中断处理
if(irqflags & IRQF_SHARED)
irqflags&= ~IRQF_DISABLED;
snprintf(hcd->irq_descr,sizeof(hcd->irq_descr), “%s:u%d”,
hcd->driver->description,hcd->self.busnum);
request_irq(irqnum,&u_hcd_irq, irqflags,hcd->irq_descr, hcd);–申请中断线
}
hcd->irq= irqnum;
} else {
hcd->irq= -1;
}
hcd->driver->start(hcd); –调用start为 ohci_s3c2410_start
rhdev->bus_mA= min(500u, hcd->power_budget);
register_root_hub(hcd)); –注册root hub
retval =sysfs_create_group(&rhdev->dev.kobj, &u_bus_attr_group);
if (retvaluses_new_polling && hcd->poll_rh)
u_hcd_poll_rh_status(hcd);
returnretval;
}
那一一来看上面的函数,学习内核就要有打破砂锅问到底的精神,唯有知道那背后的种种风光,才能领略那种种风采。闲话不说,继续!
记住下面结构体中flag的值。那就看这几个宏定义是什么意思。
#defineHCD_MEMORY 0x-hc的寄存器使用memory映射
#defineHCD_LOCAL_MEM 0xhc使用local memory
#defineHCD_USB11 0xu1.1
#defineHCD_USB2 0xu2.0
static const struct hc_driver ohci_s3c2410_hc_driver=
{
.flags =HCD_USB11 | HCD_MEMORY,
};
为hcd分配缓冲池,当hc需要使用DMA内存分配器。
int hcd_buffer_create(struct u_hcd *hcd)
{
charname;
inti, size;
if(!hcd->self.controller->dma_mask &&
!(hcd->driver->flags &HCD_LOCAL_MEM))
return 0;
–#define HCD_BUFFER_POOLS 4
我们查看pool_max其实是一个全局数组。如果需要开辟的缓冲区更大的话,直接采用分配page的函数。
static const size_tpool_max = {
32,128,512,PAGE_SIZE/ 2
};
for (i = 0; ipool = dma_pool_create(name,hcd->self.controller,size, size, 0);
if(!hcd->pool ) {
hcd_buffer_destroy(hcd);
return-ENOMEM;
}
}
return 0;
}
dma_pool_create创建一个DMA池(生成一个dma_pool,并没有分配相应空间,真正分配物理内存将在dma_pool_alloc()总实现)。
下面的函数是u_bus注册,对于该函数也许很难理解。不过参照网上
的说明,估计会好理解很多。
每个主机控制器拥有一个USB系统,称为一个USB总线。USBD支持多个主机控制器,即多个USB总线。当每增加一个主机控制器时,会给他分配一个u_bus结构。USBD动态安装和卸载主机驱动。主机驱动安装时,他的初始化函数一方面完成主机控制器硬件的设置和初始化工作,另一方面调用u_alloc_bus和u_register_bus来将自己注册到USBD中去,供USB子系统访问。
static int u_register_bus(struct u_bus *bus)
{
int result =-E2BIG;
int busnum;
mutex_lock(&u_bus_list_lock);
busnum =find_next_zero_bit (buap.buap, USB_MAXBUS, 1);
–用buap来存储主机驱动,一个bit位代表一个主机驱动
if (busnum >=USB_MAXBUS) {
return result;
}
set_bit (busnum,buap.buap);
bus->busnum = busnum;
bus->dev =device_create(u_host_class, bus->controller, MKDEV(0, 0),bus,”u_host%d”, busnum);
–在u_host类下创建一个u_host设备。
list_add(&bus->bus_list, &u_bus_list);
mutex_unlock(&u_bus_list_lock);
u_notify_add_bus(bus);
return 0;
linux dbg文件的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于linux dbg文件,Linux Debug文件详解,几个常用的linux性能监控命令,u hub的linux驱动问题求教,多谢的信息别忘了在本站进行查找喔。
成都创新互联建站主营:成都网站建设、网站维护、网站改版的网站建设公司,提供成都网站制作、成都网站建设、成都网站推广、成都网站优化seo、响应式移动网站开发制作等网站服务。
当前标题:LinuxDebug文件详解(linuxdbg文件)
转载来源:http://www.shufengxianlan.com/qtweb/news11/125711.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联