分享

软件调试

 lchjczw 2012-04-16

以下资料是我网上收集的,还没有验证过,各位看管若发现错误请指明!

看了一些资料后大致有以下几种常用的方法

1。直接到/var/log/message中查看(因为printk一般默认是打印在此处)

      或者查看/proc/kmesg  这和上面提到的有什么区别我还不知道!

2。使用命令dmesg查看信息

3。使用专门的内核模块将信息打应到指定文件或直接打印在终端显示

 

下面是一段代码应该是将内核打印信息输出到一个指定的文件中(LogFile)

[code]

#include <linux/kernel.h>

#include <linux/module.h>

#include <linux/init.h>

#include <linux/fs.h>

#include <linux/string.h>

#include <linux/mm.h>

#include <linux/syscalls.h>

#include <asm/unistd.h>

#include <asm/uaccess.h>

#define MY_FILE "/root/LogFile"

char buf[128];

struct file *file = NULL;

static int __init init(void)

{

        mm_segment_t old_fs;

        printk("Hello, I'm the module that intends to write messages to file.\n");

        if(file == NULL)

                file = filp_open(MY_FILE, O_RDWR | O_APPEND | O_CREAT, 0644);

        if (IS_ERR(file)) {

                printk("error occured while opening file %s, exiting...\n", MY_FILE);

                return 0;

        }

        sprintf(buf,"%s", "The Messages.");

        old_fs = get_fs();

        set_fs(KERNEL_DS);

        file->f_op->write(file, (char *)buf, sizeof(buf), &file->f_pos);

        set_fs(old_fs);

        return 0;

}

static void __exit fini(void)

{

        if(file != NULL)

                filp_close(file, NULL);

}

module_init(init);

module_exit(fini);

MODULE_LICENSE("GPL");

[/code]

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

以下这段代码是将内核打印信息打印在当前终端上显示

[CODE]
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/tty.h>
MODULE_LICENSE("GPL");
MODULE_AUTHOR("mq110");
static void print_string(char *str)
{
    struct tty_struct *my_tty;
    my_tty = current->signal->tty;
    if (my_tty != NULL)
    {
        my_tty->driver->write(my_tty,0,str,strlen(str));
        my_tty->driver->write(my_tty,0,"\015\013",2);
    }
}
static int __init print_string_init(void)
{
    print_string("Hello world!");
    return 0;
}
static void __exit print_string_exit(void)
{
    print_string("Goodbye world!");
}
module_init(print_string_init);
module_exit(print_string_exit);
[/CODE]

我一般用putty登陆 编写kernel module. printk信息都存在/var/log/message里了.~

用这个程序就能显示在屏幕上了.你可以把print_string 符号导出来.
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
注意printk输出你并不一定能看到,得进入字符界面时才能看到,telnet,ssh连接都看不到的,你也可以处理一下,让系统输出到你的终端:  
  /*************---printk.c-----**********/  
  /*  
  *Rectified   by   duanjigang@2006-3-19  
  *desp:将提示信息输出到当前用户的终端tty,使用telnet   or   ssh连接的用户将会看到  
  *在当前终端输出的提示信息  
  */  
  #include   <linux/kernel.h>  
  #include   <linux/module.h>  
  #ifdef   CONFIG_MODULEVERSIONS  
  #define   MODULEVERSIONS  
  #include   <linux/moduleversions>  
  #endif  
  MODULE_LICENSE("GPL");  
  MODULE_AUTHOR("duanjigang");  
   
  #include   <linux/sched.h>/*For   current*/  
  #include   <linux/tty.h>   /*For   tty   declarations*/  
   
  void   print_string(char   *str)  
  {  
      struct   tty_struct   *   my_tty;  
      /*获得当前进程的tty,写到标准输出*/  
      my_tty   =   current->tty;  
      if(my_tty   !=   NULL)  
      {  
          (*(my_tty->driver).write)(my_tty,   0   ,str,   strlen(str));  
          (*(my_tty->driver).write)(my_tty,   0   ,"\015\012",   2);  
      }  
  }  
   
  int   init_module()  
    {  
      print_string("module   inserted!");  
      return   0;  
    }  
  void   cleanup_module()  
  {  
    print_string("module   cleaned!");  
  }  
   
  Makefile  
  #Author:   duanjigang   <duanjigang1983@126.com>   <duanjigang@hotmail.com>  
  #Date:     2006-3-19  
  CC=cc  
  CFLAG   :=   -Wall   -DMODULE   -D__KERNEL__   -DLINUX    
  printk.o:printk.c   /usr/include/linux/version.h  
  $(CC)   $(CFLAG)   -c       printk.c   -I   /usr/src/linux-2.4.20-8/include  
  install:  
  insmod   printk.o    
  clean:  
  rm   -f   *.o    
   
  root@localhost   2]#make  
  cc   -Wall   -DMODULE   -D__KERNEL__   -DLINUX     -c       printk.c   -I   /usr/src/linux-2.4.20-8/include  
  root@localhost   2]#   insmod   printk.o  
  module   inserted!  
  [root@localhost   2]#   rmmod   printk    
  module   cleaned!  
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
printk输出跟输出的日志级别有关系,当他的输出日志级别比控制台的级别高时,就会显示在控制台上,当他比控制台低时,只是记录在/var/log/message中.但是当系统同时运行了klogd和syslogd时,都追加到/var/log/message.在/proc/sys/kernel/printk文件中,前两个整数为当前的日志级别和默认的日志级别(默认的日志级别即为printk的输出级别).printk带日志的的输出方式如下:  
  printk(<3>"here   I   am:%s%d",__FILE__,__LINE__); 
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
printk不显示在超级终端上,保存在/var/log/messages。

可以通过dmesg命令查看,如果只想显示最后几行,可以用
dmesg   |   tail   -   8

驱动一般是软硬件联调

软件方法有:
1.   用打印调试(printk)
2.   使用   /proc   文件系统调试
3.   用strace   命令观察调试
4.   使用kgdb   调试
(软件调试方法可以参考Linux   Device   Driver   3rd     Chapt   04

硬件调试一般是用示波器探测波形。
http://www.360doc.com/

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多