Linux Debug文件详解 (linux dbg文件)

在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文件。

相关问题拓展阅读:

几个常用的linux性能监控命令

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

u hub的linux驱动问题求教,多谢

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驱动问题求教,多谢的信息别忘了在本站进行查找喔。


数据运维技术 » Linux Debug文件详解 (linux dbg文件)