`
helloyesyes
  • 浏览: 1303937 次
  • 性别: Icon_minigender_2
  • 来自: 武汉
文章分类
社区版块
存档分类
最新评论

Linux编程学习(续二)

阅读更多

信号处理

信号相当于DOS下的Int或者Windows下的消息。

Kill –l命令可以查看各种信号信息。

man 7 signal可查看各个信号的具体解释。

软件原因和硬件原因都会产生信号。

常用的发信号的函数包括:

kill

raise

alarm

setitimer

killpid_t pid , int sig

调用kill可以向任何进程组或者进程发送任何信号。

Raise用来向自己发送信号sig,它等于killgetpid(),sig

Alarm函数在seconds秒后向自己发送一个SIGALRM信号。比如下面程序:

#include <stdio.h>

#include <unistd.h>

main()

{

unsigned int i;

alarm(1);

for(i = 0; 1 ; i++)

printf("I = %d",i);

}

SIGALRM的缺省操作是结束进程,因此1秒钟以后,你可以看到最后的I值是多少。

使用信号屏蔽可以使进程不受到信号的打扰。信号屏蔽用到几个函数:

int sigemptyset(sigset_t *set);

int sigfillset(sigset_t *set);

int sigaddset(sigset_t *set,int signo);

int sigdelset(sigset_t *set,int signo);

int sigismember(sigset_t *set,int signo);

int sigprocmask(int how,const sigset_t *set,sigset_t *oset);

下面例子演示了函数的使用:

#include <stdio.h>

#include <signal.h>

#include <stdlib.h>

int main(int argc,char **argv)

{

double y;

sigset_t intmask;

int i;

int repeat_factor;

if(argc != 2)

{

fprintf(stderr,"Usage:%s repeat_factor\n\a",argv[0]);

exit(1);

}

if((repeat_factor = atoi(argv[1])) < 1)

repeat_factor = 10;

sigemptyset(&intmask); //Initializes the signal set given by set to empty.

sigaddset(&intmask,SIGINT); //Add signal of INT Ctrl+C

while(1)

{

//Block signal and no saveed signal set.

sigprocmask(SIG_BLOCK,&intmask,NULL);

fprintf(stderr,"SIGINT signal blocked\n");

for(i = 0; i<repeat_factor ; i++)

fprintf(stderr,"blocked calculation is finished\n");

//UnBlock signal

sigprocmask(SIG_UNBLOCK,&intmask,NULL);

fprintf(stderr,"SIGINT signal unblocked\n");

for(i = 0; 1<repeat_factor ; i++)

fprintf(stderr,"Unblocked calculation is finished\n");

}

exit(0);

}

另一个有用的函数是sigaction,用来指定一个信号的处理行为。下面例子捕捉CtrlC的信号,并输出一个提示。

//function sigaction test.

#include <stdio.h>

#include <signal.h>

#include <stdlib.h>

#include <unistd.h>

#include <errno.h>

#define PROMPT "Do you want to exit this program?"

char * prompt = PROMPT;

void ctrl_c_op(int signo)

{

write(STDERR_FILENO,prompt,strlen(prompt));

}

int main(int argc,char **argv)

{

struct sigaction act;

act.sa_handler = ctrl_c_op;

sigemptyset(&act.sa_mask);

act.sa_flags = 0;

if(sigaction(SIGINT,&act,NULL) < 0)

{

fprintf(stderr,"Install Signal Action Error:%s\n\a",strerror(errno));

exit(1);

}

while(1);

exit(0);

}

还有一些很用于的关于信号方面的函数,比如:

pause

sigsuspend

sigsetjmp

siglongjmp

上面一些函数对于信号处理来说能够应付一般需要,其实信号的处理远非这些。

PS命令,列举当前系统中的进程信息

PS –A

Manwhatisapropos

Man命令是Linux下常用的参考文档。有两个配合使用的命令,就是whatis和。Aproposwhatis是全匹配,apropos是关键字匹配。比如,manager这个词,如果“whatis man”,就匹配不到,但apropos man则能够匹配到。

查找运行时的权能

sysconf函数用来查询运行时的权能。比如,对传递给一个新程序的字符串参数的长度进行限制,可以保护系统不被任意分配内存的要求所破坏。比如下面代码:

#include <stdio.h>

#include <unistd.h>

main()

{

printf("The number of clock ticks per second: %d\n",sysconf(_SC_CLK_TCK));

printf("The maximum length of the arguments to the exec() family of functions: %d\n",sysconf(_SC_ARG_MAX));

printf("The maximum number of files that a process can have open at any time: %d\n",sysconf(_SC_OPEN_MAX));

exit(0);

}

查找和设置系统的基本信息

使用uname函数。

Bug测试和调试

下面是一段测试代码,代码破坏了三种内存区域:

l malloc从动态内存池中分配的内存

l 在程序堆上分配的本地变量

l 在程序启动时候被静态分配的并保存在分散内存区域中的全局变量

#include <stdlib.h>

#include <stdio.h>

#include <string.h>

char global[5];

int broken(void)

{

char * dyn;

char local[5];

dyn = malloc(5);

strcpy(dyn,"12345");

printf("1: %s \n",dyn);

free(dyn);

dyn = malloc(5);

strcpy(dyn,"12345678");

printf("2: %s \n",dyn);

*(dyn - 1) = '\0';

printf("3: %s \n",dyn);

strcpy(local,"12345");

printf("4: %s \n",local);

local[-1] = '\0';

printf("5: %s \n",local);

strcpy(global,"12345");

printf("6: %s \n",global);

global[-1] = '\0';

printf("7: %s \n",global);

return 0;

}

int main(void)

{

return broken();

}

尽管从代码中已经发现问题,但实际上程序运行得很好。下面是结果。

<shapetype id="_x0000_t75" stroked="f" filled="f" path="m@4@5l@4@11@9@11@9@5xe" o:preferrelative="t" o:spt="75" coordsize="21600,21600"><stroke joinstyle="miter"></stroke><formulas><f eqn="if lineDrawn pixelLineWidth 0"></f><f eqn="sum @0 1 0"></f><f eqn="sum 0 0 @1"></f><f eqn="prod @2 1 2"></f><f eqn="prod @3 21600 pixelWidth"></f><f eqn="prod @3 21600 pixelHeight"></f><f eqn="sum @0 0 1"></f><f eqn="prod @6 1 2"></f><f eqn="prod @7 21600 pixelWidth"></f><f eqn="sum @8 21600 0"></f><f eqn="prod @7 21600 pixelHeight"></f><f eqn="sum @10 21600 0"></f></formulas><path o:connecttype="rect" gradientshapeok="t" o:extrusionok="f"></path><lock aspectratio="t" v:ext="edit"></lock></shapetype><shape id="_x0000_i1025" style="WIDTH: 364.5pt; HEIGHT: 123pt" type="#_x0000_t75"><imagedata o:title="001" src="file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/msoclip1/01/clip_image001.jpg"></imagedata></shape>

为了发现问题,需要借助调试工具:

MALLOC_CHECK_,工具用于进行堆数据结构得一致性检查。有几种调试参数:

MALLOC_CHECK_=0 ./broken

MALLOC_CHECK_=1 ./broken

MALLOC_CHECK_=2 ./broken

最有用的是最后一句,一旦发现错误,工具将把我们带到错误发生点最近的地方。

这样用则更好:

$ MALLOC_CHECK_2 gdb ./broken

下面是部分调试信息:

GNU gdb Red Hat Linux (5.3post-0.20021129.18rh)

Copyright 2003 Free Software Foundation, Inc.

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

welcome to change it and/or distribute copies of it under cer tain 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 "i386-redhat-linux-gnu"...

(gdb) r

Starting program: /home/lx/csource/bugtest/broken

1: 12345

Program received signal SIGABRT, Aborted.

0xffffe002 in ?? ()

(gdb) where

#0 0xffffe002 in ?? ()

#1 0x42028a73 in abort () from /lib/tls/libc.so.6

#2 0x42075e09 in free_check () from /lib/tls/libc.so.6

#3 0x42073485 in free () from /lib/tls/libc.so.6

#4 0x0804840b in broken ()

#5 0x08048500 in main ()

#6 0x42015574 in __libc_start_main ()

from /lib/tls/libc.so.6

(gdb)

另一种调试方法是链接mcheck库函数,方法是:

[lx@ssss bugtest]$ gcc -ggdb -o broken broken.c -lmcheck

[lx@ssss bugtest]$ ./broken

1: 12345

memory clobbered past end of allocated block

mcheck只能打印错误信息,并不能指明错误所在,因此需要在gdb内运行程序。

版本问题

带奇数的内核版本(即 2.32.52.7 等)是实验性的开发版内核。稳定的发行版内核的版本号是偶数(即 2.42.62.8 等)。

=待续=

分享到:
评论

相关推荐

    linux c编程源码

    在Linux环境下进行C编程是一项基础且重要的技能,尤其在服务器端和嵌入式系统开发中。...以上是Linux环境下进行C编程所需掌握的关键知识点,通过深入学习和实践,你将能够编写出高效、稳定且适应各种Linux系统的C程序。

    FTP_linux.rar_FTP_linux_Linux FTP源代码_ftp断点续传_linux ftp_断点上传

    本设计实现了ftp的设计,使用了socket网络编程,ftp基于cs模式,包含客户端和服务端,可以实现上传、下载、删除、...运行环境是linux,压缩包内含有源代码、使用说明、实验报告等,是学习linux和网络编程的上等材料。

    linux-FTP客户端(纯C代码)

    在给定的压缩包文件"ftp"中,可能包含了实现这些功能的C源代码,供学习和参考。通过阅读和分析这些代码,可以深入了解FTP客户端的工作原理和C语言在网络编程中的应用。不过,为了实现更高级的功能,如断点续传,需要...

    基于UDP协议的Client/Server linux网络编程

    【标题】:“基于UDP协议的Client/Server Linux网络编程” 在计算机网络中,UDP(User Datagram Protocol,用户数据报协议)是一种无连接的传输层协议,它提供了比TCP(Transmission Control Protocol,传输控制...

    linux与unix shell编程指南2(续1)

    全书目录在本压缩包内。 本书共分五部分,详细介绍了shell编程技巧,各种UNIX命令及语法,还涉及了UNIX下的文字处理以及少量的系统管理问题。本书内容全面、文字简洁流畅,适合Shell编程人员学习、参考。

    从Windows转向Linux教程E3000基础学习.pdf

    ### 从Windows转向Linux...以上内容覆盖了从Windows转向Linux的过程中所需要掌握的基本知识点,不仅包括了操作系统本身的使用,还涉及到了软件安装、网络配置、编程开发等多个方面,为初学者提供了一个全面的学习指南。

    linux下的DHCP源代码

    通过研究这些源代码,开发者不仅可以深入理解DHCP协议,还可以学习到网络编程、系统级编程、多线程编程等多个领域的知识,对于提升自身的技能水平大有裨益。同时,这也为定制化DHCP服务器、开发相关工具或修复潜在...

    嵌入式Linux视频教程全套2011新版-国嵌嵌入式培训下载地址

    #### 二、嵌入式Linux应用开发 **2.1 国嵌课程2-嵌入式Linux应用开发班** - **第1天(编程基础)** - **GCC程序编译**: 讲解如何使用GCC编译器编译C/C++程序。 - **GDB程序调试**: 教授如何使用GDB进行程序调试...

    Linux环境下socket编程,实现简单的FTP上传下载功能

    在Linux环境下,Socket编程是构建网络应用程序的基础,它允许程序之间通过网络进行通信。FTP(File Transfer Protocol)是一种用于在互联网上进行文件传输的标准协议。本教程将介绍如何使用Linux的socket API来实现...

    Linux系统下dhcp源码

    本文将探讨dhcp-3.1.1版本的源码,通过分析源码,我们可以学习到Linux网络编程、TCP/IP协议栈和DHCP协议的细节。 1. **DHCP协议基础** DHCP协议基于UDP,使用客户端/服务器模型。在Linux环境下,DHCP服务端通常...

    Linuxsocket文件传输(C语言,支持断点)

    在Linux系统中,Socket编程是实现网络通信的一种基础方式,它可以...总之,这个项目涉及到Linux Socket编程的核心概念,包括连接建立、文件传输和断点续传的实现,对于理解和实践网络编程以及文件传输具有很高的价值。

    嵌入式linux开发应用程序开发详解

    **第11章 嵌入式Linux设备驱动开发(续)** 这部分进一步探讨中断处理、DMA(直接存储器访问)、设备驱动框架,以及如何调试驱动程序。 **第12章 Qt图形编程** Qt是一个流行的跨平台GUI库,适合在嵌入式设备上创建...

    LINUX下传输文件源码

    对于初学者,可以从中学习到C语言在Linux环境下的文件操作和网络编程知识;对于有经验的开发者,可以借鉴其中的实现策略,改进自己的代码。 由于没有具体的源码可供分析,以上内容是对基于C语言的Linux文件传输程序...

    网络编程之文件服务器.rar

    综上所述,“网络编程之文件服务器.rar”可能包含了创建文件服务器的源代码、文档或者示例,这些内容可以帮助开发者学习如何在Linux环境下构建一个支持断点续传功能的网络文件服务器。通过深入研究和实践,不仅可以...

    猪哥的嵌入式linux公房菜

    - **中级阶段**:深入学习Linux内核、设备驱动等。 - **高级阶段**:项目实战、性能优化等。 **4. 嵌入式Linux入门学习内容指南** - **操作系统原理**:了解Linux内核架构。 - **编程技术**:学习C语言和Shell脚本...

    FTP.rar_ftp 查找 linux_ftp linux_linux ftp_linux ftp_linux下ftp

    在Linux操作系统中,FTP...总结,这个压缩包可能包含了Linux环境下使用FTP的相关教程、源代码示例,对于学习FTP的使用、实现及安全配置具有很高的价值。通过深入学习和实践,可以提升在Linux系统中进行文件传输的能力。

    linux下ftp实现

    在Linux操作系统中,FTP(File Transfer Protocol)是一种用于在计算机之间传输文件的标准网络协议。它允许用户通过命令行界面或...通过阅读和分析这些代码,可以增强对网络协议和Linux编程的理解,提高问题解决能力。

    LinuxTool, Linux下常用工具及其命令介绍.zip

    以上只是LinuxTool项目中一小部分工具和命令的介绍,实际内容可能更丰富,包括但不限于文件压缩与解压缩、权限管理、脚本编程等方面。通过学习和熟练运用这些工具,可以在Linux环境中更加得心应手。对于开发者而言,...

    LinuxPPT.rar

    这个名为"LinuxPPT.rar"的压缩包文件包含了深入学习Linux操作系统的丰富资源,涵盖了从基础到进阶的多个主题,适合对Linux感兴趣的初学者和希望提升技能的IT从业者。 首先,"第1章认识Linux.pptx"介绍了Linux的历史...

Global site tag (gtag.js) - Google Analytics