当前位置:首页 > 问答 > 正文内容

[操作系统]Linux程序开发调试(from our experiment)(转载)

风约清莲6年前 (2018-12-10)问答104
印刷厂直印●彩页1000张只需要69元●名片5元每盒-更多报价➦联系电话:138-1621-1622(微信同号)

实验 Linux程序开发调试

  一. 实验目的

  通过本实验的训练,应掌握Linux程序开发与调试的基本技术。初步了解framebuffer、Gnome/Gtk+和KDE/Qt编程的基本方法。

  二. 实验内容

  1、 使用vi编写一个hello.c程序(在终端上打印“hello world!”),用gcc编译并运行。

  2、 为上述的hello.c编写Makefile,要求能用make命令创建可执行程序hello;用make clean清除上次编译结果;用make debug创建 可用GDB调试的可执行程序hello。

  3、 分析u-boot-1.1.2的Makefile。

  4、 用GDB/INSIGHT调试《LINUXUNIX程序开发基础教程 》第12章第173页的bugged.c

  5、 学习三种不同的图形编程技术:framebuffer、Gnome/Gtk+和KDE/Qt,并分别用它们完成一个显示320x240分辨率BMP图片的小程序。

  三、基本原理

  本实验的内容在装有Linux的PC机上完成,需要装有gcc、autoconf、automake、make等开发工具,另外还需要有kdevelop、designer和Glade工具软件。Redhat Linux在安装时要选择Development、Gnome Development和KDE Development软件包。

  参考资料:

  1、 LINUX编程资料

  LINUXUNIX程序开发基础教程

   Sarwar, AI-Saqabi著,英宇 姚锋译,清华大学出版社

  Unix环境高级编程 W.Richard Stevens著,尤晋元译,清华大学出版社

  Unix网络编程v1 v2 W.Richard Stevens著,清华大学出版社

  The GNU C Library Reference Manual

  /

  2、 gcc资料

  GCC Manual /

  GCC技术参考大全 (GCC Manual的中文译本),清华大学出版社,胡恩华 译

  3、 GDB资料

  GDB Manual /

  4、 Makefile资料

  GNU make Manual

  Managing Projects with GNU make

   Robert Mecklenburg著(电子书)

  5、 图形编程

  Framebuffer编程 Linux程序设计权威指南,机械工业出版社,于明俭 等编著

  Kdevelop

021yin.com /3.2/designer-manual.html

  GTK Manual API Reference

   /

  GTK2 Tutorial中文版

021yin.com /gtk/book1.html

  三. 实验步骤

  1. 用gcc开发hello world程序

  Gcc是Linux编程中最常用的编译工具。用vi编写如下的hello world程序,并用gcc编译。

  [root$xmu root]# vi hello.c

  #include stdio.h

  int main()

   printf(“hello world\n”);

   return 0;

  [root$xmu root]# gcc -o hello hello.c

  [root$xmu root]# ./hello

  hello world

  [root$xmu root]#

  以上的编译语句中,hello.c是源程序名,‘-o’参数表示把结果输出到某个文件,也就是把编译hello.c生成的二进制代码输出到hello文件。

  2. Makefile编写与分析

  Makefile是一个由若干条规则组成的文本文件,再运行make时会自动读取该文件,并按照规则的约定完成一系列的动作。Makefile广泛使用在Linux下各种软件的源代码中。自己编写一个简单的Makefile来完成编译hello world程序的工作,以下是一个样例,

  # sample Makefile

  CC=gcc

  hello: hello.c

   $(CC) -o $@ $

  .PHONY: clean

  clean:

   rm -f hello

  3. GDB/insight调试工具的使用

  GDB是Linux下常用的调试工具,我们使用GDB来发现程序里的bug,或者找到程序崩溃的原因等。GDB可以:

  ·启动你的程序,并可以指定某些参数控制程序的行为。

  ·使你的程序在特定的条件下停止。

  ·当你的程序停止时,检查程序的状态。

  ·改变程序中的参数,这样你就可以暂时避过某个bug,继续查找其他的问题。

  (1) 安装GDB

  GDB的源代码可以从的安装

  [root$xmu root]# tar xvzf gdb-6.2.tar.gz

  [root$xmu root]# cd gdb-6.2

  [root$xmu gdb-6.2 ]# ./configure

  [root$xmu gdb-6.2 ]# make

  [root$xmu gdb-6.2 ]# make install

  这是最简单的安装本地使用的GDB的方法。configure的其他参数可以运行“./configure –help”获得。

  (2) GDB的运行

  使用GDB调试程序,首先要保证程序在编译时使用了-g参数,否则生成的二进制代码中不会包含调试信息。

  运行gdb即可启动GDB。启动后,GDB就开始从终端读取命令,直至退出。启动GDB时也可以带有其他的选项。启动GDB最常见的方式是带有一个指定被调试程序名的选项:

  [root$xmu root]# gdb programe

  如果是调试正在运行的程序,要再加上它的进程ID:

  [root$xmu root]# gdb program process_id

  使用--args选项,可以给程序传递参数:

  [root$xmu root]# gdb –args foo hello

  这条命令对foo进行调试,foo运行的参数为“hello”。

  启动GDB后,就进入了GDB Shell,所有后续的GDB命令都是在GDB Shell下解释执行的。在GDB Shell中键入quit或者q命令就退出GDB。退出GDB也可以使用Ctrl+d,Ctrl+c不会退出GDB,但会使正被调试的程序终止。

  GDB是基于命令行的纯文本调试器,使用起来会感到有些不便,特别是对初学者。Insight是GDB的一个图形版本,它的核心仍然是GDB,只是给GDB增加了一个图形窗口的外壳,使GDB使用起来更加顺手。Insight的源代码可以从。

  [root$xmu root]# tar xvjf insight-6.1.tar.bz2

  [root$xmu root]# cd insight-6.1

  [root$xmu insight-6.1]# ./configure --prefix=/path/to/your/install/directory

  [root$xmu insight-6.1]# make

  [root$xmu insight-6.1]# make install

  configure命令中的prefix表示要将insight安装到何目录,默认值为/usr/local,你也可以改变这个参数。安装之后启动XWindows,就可以运行insight了。如果提示找不到insight程序,可能是insight的安装路径没有包含在PATH环境变量中,通过下面的命令可临时修改,

  #[root$xmu root]# export PATH=$PATH:/path/to/your/install/directory/bin

  也可以在用户登录时自动设置该变量,

  #[root$xmu root]# vi ~/.bash_profile

  PATH=$PATH:$HOME/bin

  PATH=$PATH:/path/to/your/install/directory/bin szlig;增加此行

  #[root$xmu root]# source ~/.bash_profile

  再运行insight即可。

  从insight中打开一个二进制可执行程序,相应的源代码也会显示在窗口中,可以在代码中设置断点,增加观察变量,单步跟踪程序运行。

  (3) 测试代码

  编写如下测试代码

  ~/hello.c

  #include stdio.h

  main()

   char *str = NULL ;

   strcpy(str,“hello, world“);

   printf(“str is %s \n“, str);

   return;

  模拟使用空指针产生的错误。编译这段代码,

  [root$xmu temp]# gcc -g hello.c -o hello

  (4) 调试

  用GDB加载hello

  [root$xmu ~]# gdb hello

  GNU gdb 6.3

  Copyright 2004 Free Software Foundation, Inc.

  GDB is free software, covered by the GNU General Public License, and you are

  welcome to change it and/or distribute copies of it under certain conditions.

  Type “show copying“ to see the conditions.

  There is absolutely no warranty for GDB. Type “show warranty“ for details.

  This GDB was configured as “i686-pc-linux-gnu“...Using host libthread_db library “/lib/tls/libthread_db.so.1“.

  (gdb)

  接下来开始调试程序。

  (gdb) list

  1 #include stdio.h

  2

  3 main()

  4 {

  5 char *str = NULL ;

  6

  7 strcpy(str,“hello, world“);

  8 printf(“str is %s \n“, str);

  9

  10 return;

  11 }

  为了调试空指针引起的错误,在第7行设置断点,

  (gdb) break 7

  Note: breakpoint 1 also set at pc 0x83ec.

  Breakpoint 1 at 0x83ec: file hello.c, line 7.

  执行代码并单步跟踪,

  (gdb) cont

  Continuing.

  Breakpoint 1, main () at hello.c:7

  7 strcpy(str,“hello, world“);

  (gdb) step

  Program received signal SIGSEGV, Segmentation fault.

  0x4009a8f8 in ?? ()

  可以看到在程序的第7行执行时出现了一个段错误,段错误通常是由内存的非法访问引起的。

  4. FrameBuffer编程

  Linux下的FrameBuffer设备是一个抽象的图形设备,它可以使应用程序直接访问图形硬件设备。设备节点是/dev/fb*,需要在编译内核时支持FrameBuffer,并且在系统启动时设置为FrameBuffer工作模式。例如,使用lilo引导Linux,在/etc/lilo.conf中设定boot:linuxvga=xxx;或使用grub引导Linux,在/boot/grub/grub.conf的kernel一行末尾添加vga=xxx。其中xxx是FrameBuffer的不同模式,

   640×480 800×600 1024×768 1280×1024

  256(8位) 769 771 773 775

  32k(15位) 784 787 790 793

  64k(16位) 785 788 791 794

  16M(32位) 786 789 792 795

  这种设置仅适用于vesa vga图形终端。多数嵌入式平台并不是这种类型,设置参数也各有不同,但原理类似。

  FrameBuffer编程的基本步骤是:

  (1) 打开framebuffer设备并查询设备信息;

  (2) 设置颜色表(可选);

  (3) 初始化设备;

  (4) 向设备写数据;

  (5) 关闭设备;

  其中设置颜色表在这里不作介绍。在这个实验中,我们要实现将一幅24位色320×240的bmp格式图片显示在16位色模式的FrameBuffer中。

  (1) 打开fb设备

  int fd;

  struct fb_fix_screeninfo finfo;

  struct fb_var_screeninfo vinfo;

  fd = open(“/dev/fb0“, O_RDWR);

  if (!fd) {

   printf(“Cannot open framebuffer device.\n“);

   exit(1);

  printf(“The framebuffer device was opened successfully.\n“);

  if (ioctl(fd, FBIOGET_FSCREENINFO, finfo)) {

   printf(“Error reading fixed information.\n“);

   exit(1);

  if (ioctl(fd, FBIOGET_VSCREENINFO, vinfo)) {

   printf(“Error reading variable information.\n“);

   exit(1);

  fb_fix_screeninfo和fb_var_screeninfo结构体的定义可以在/usr/include/linux/fb.h中找到。其中,比较重要的是smem_start和smem_len两个数据,分别是物理起始地址和映射长度。

  (2) 初始化

  unsigned long fb_smem_addr, fb_smem_len, fb_mem_offset, fb_line_length;

  mmap函数可以把文件或设备映射到内存空间,这里就是把framebuffer设备映射到内存空间,长度为fb_smem_len+fb_mem_offset。这样,向这个空间写入数据就可以在屏幕上显示出相应的图象。映射内存的长度等于全屏像素总数与存储每个像素占用字节数的乘积,例如320×240 256色,即为320×240×1。

  (3) 写数据

  内存映射区初始化完成后,就可以向其中写入数据了,写的方法就是一个一个像素的进行,具体与颜色深度有关。实验中采用16位色模式,其他模式可参考相关资料。

  unsigned char *dest;

  dest = fb_mem + fb_line_length * y + (x 1);

  dest是要写入的目标地址,x和y分别为像素的横纵座标,以左上角为圆点,横轴向右,纵轴向下计算。因为是16位色,所以每个像素占用两个字节,计算偏移量的时候要把x1,显示一个像素要向dest中写入两个字节。其他不同位色模式的操作与此类似。

  创建一个24位色的bmp图片,我们从文件中可以读到每个像素的8位RGB值,只要把24位转换成16位就可以写入内存映射区了。一个16位颜色是这样安排的,

  15 11 10 5 4 0

  Red (5bits) Green (6bits) Blue (5bits)

  取RGB各自的高位填充到这个16位数据中即可。最后把这个组装好的数据写入dest指向的内存。

  如果在显示图形之前需要清屏,只要往内存映射区写入全0值即可,

  memset(fb_mem + fb_mem_offset, 0, fb_smem_len);

  (4) 关闭fb设备

  close(fd);

  附bmp文件格式:

  00 – 01 字符“BM”作为bitmap文件标识符

  02 – 05 文件总字节数

  06 – 09 保留位

  10 – 13 实际像素数据距文件头的偏移值

  14 – 17 数据头部字节数(通常是40)

  18 – 21 位图宽度(像素)

  22 – 25 位图高度(像素)

  26 – 27 调色板数量(通常为1)

  28 – 29 每像素位数,可以是1、4、8、16、32。

  30 – 33 无损压缩模式,0表示无压缩

  34 – 37 像素数据字节数

  38 – 41 宽度方向每米像素数

  42 – 45 高度方向每米像素数

  46 – 49 实际使用的色彩数

  50 – 53 重要颜色数

  54 – end 像素数据

  可以看出,实际的像素数据是从第55字节开始的。在无压缩模式下,每个像素按照8位蓝色字节,8位绿色字节和8位红色字节的顺序记录。像素由图像左下角开始,一行一行地记录,即由底向上,由左向右。在程序中读取像素值时要注意不要搞错顺序,包括像素的排列顺序和像素中三种颜色的顺序。

  5. KDE/Qt编程

  KDE是一种UNIX工作站常用的桌面环境,使得UNIX工作站的使用更加方便。Qt是一个多平台的C++图形用户界面应用程序框架。它提供给应用程序开发者建立艺术级的图形用户界面所需的功能。在以下实验中,我们将使用kdevelop(KDE集成开发环境)和designer(QT设计器)两个工具完成一个简单的基于KDE的桌面图形程序开发。我们以RedHat Linux 9.0中预装的kdevelop-2.1.5和QT designer-3.1为例,其他版本在界面上可能略有不同。

  (1) 打开“ProgrammingàKDevelop”,从Project菜单中新建一个名为“kdemini”的KDE Mini工程,除了工程的路径和名字,其他均保留默认设置即可。按下“Create”,即自动创建工程,等待READY字样出现则工程创建完成。

  (2) 从Build菜单中执行“Make”,对工程进行编译,等待“Success”字样出现后,再从Build菜单中执行“Excute”,执行这个程序。此时应出现一个空的窗口,说明工程编译成功,已经产生了一个最简单的窗口。

  (3) 打开“Programmingàdesigner”,从File菜单中新建一个“Main Window”文件。接下来可以按照自己的想法设计窗口界面,屏幕左边是控件栏,右边是属性栏,使用起来很简单。只要在窗口中添加几个部件使它看起来不像刚才那么简单即可。将这个文件保存在kdemini工程目录下的kdemini目录中,命名为interface.ui。

  (4) 从Project菜单中执行“Add existing file”,把interface.ui加入工程中。从Build菜单中执行“Autoconf and automake”,再执行“Configure”(无参数),最后执行“Make”。此时将会在kdemini目录中生成interface.h和interface.cpp两个文件。

  (5) 打开interface.h,看其中类的名字,默认为Form1。打开kdemini.h,增加

  #include “interface.h”

  把class Kdemini : public Qwidget

  改为class Kdemini : public Form1

  打开kdemini.cpp,把Kdemini::Kdemini(QWidget *parent, const char *name) : QWidget(parent, name)

  改为Kdemini::Kdemini(QWidget *parent, const char *name) : Form1(parent, name)

  这样,就把我们设计好的界面添加到了kdemini工程中。

  (6) 再运行Make,然后Excute,就可以看到程序的窗口变成了用QT designer设计好的样式。

  以上就是一个简单KDE桌面程序的开发过程,关于kdevelop和designer的功能和用法制设计到了很少的一点。Kdevelop是一个集成开发环境,拥有编辑器、编译、调试等全面的功能;使用QT designer可以设计出各种风格的界面,不仅可以添加控件,也可以定义控件的事件等。所以,使用QT designer作为设计,使用kdevelop编译调试,就可以开发出界面友好运行稳定的KDE桌面图形程序。

  6. Gnome/Gtk+编程

  Gnome是Linux中另外一种常用的桌面环境,下面使用Glade工具来设计一个基于Gnome的桌面图形程序。在PC机上启动XWindows界面,运行ProgramàGlade Interface Designer程序

  二. 新建GTK+工程。

  三. 从“调色板”中选择“窗口”,生成一个GTK窗口,从属性窗口中修改窗口标签为“test”。

  四. 从“调色板”中选择“固定位置”控件,置于test窗口中。

  五. 从“调色板”中选择“标签”和“按钮”控件置于test窗口中,修改标签为“hello, this is a test program”和“Close”。

  六. 选中按钮“Close”,在属性窗口中添加一个“clicked”事件,命名为on_window_close。

  七. 选择“查看à显示构件树”,可以列出所有的窗口部件,选中主窗口,在属性窗口中添加一个“delete_event”事件,也叫做on_window_close。

  八. 保存工程于/root/test_gtk。然后联编(Build)工程。

  九. 编辑/root/test_gtk/src/callbacks.c,将on_window_close()函数修改为,

  gboolean on_window_close(GtkWidget *widget,

   GdkEvent *event,

   gpointer user_data)

   gtk_main_quit();

   return FALSE;

  函数gtk_main_quit()使主窗口销毁。

  十. 运行,

  [root$ ]# cd /root/test_gtk

  [root$test_gtk]# ./autogen.sh

  [root$test_gtk]# make

  编译test_gtk程序,如果没有错误,会生成src/test_gtk,可以运行这个程序看看效果。

  四. 思考题

  1、 LINUX下调试应用程序有几种方法?

  2、 试比较gdb与insight调试程序的异同。

  3、 试比较framebuffer、QT、GTK三种图形编程方法的优缺点。

收藏0

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。