Linux学习总结(1)

Linux内核与Valgrind工具详解

1.查找当前系统中的内核目录

(1)使用:uname -r查看当前内核版本号

[root@NetValve ulog-acctd]# uname -r
2.6.21.2
(2)进入到/lib/modules/目录下

然后进入系统内核版本号的的目录,也就是/lib/modules/2.6.21.2

(3)使用ls -l查看记录

[root@NetValve 2.6.21.2]# ls -l
total 72
lrwxrwxrwx 1 root root   25 Oct 31 16:11 build -> /usr/src/kernels/2.6.21.2
drwxr-xr-x 6 root root 4096 Oct 31 16:11 kernel
-rw-r--r-- 1 root root 4850 Nov  1 12:42 modules.alias
-rw-r--r-- 1 root root   69 Nov  1 12:42 modules.ccwmap
-rw-r--r-- 1 root root 6807 Nov  1 12:42 modules.dep
-rw-r--r-- 1 root root   73 Nov  1 12:42 modules.ieee1394map
-rw-r--r-- 1 root root  141 Nov  1 12:42 modules.inputmap
-rw-r--r-- 1 root root   81 Nov  1 12:42 modules.isapnpmap
-rw-r--r-- 1 root root   74 Nov  1 12:42 modules.ofmap
-rw-r--r-- 1 root root 6014 Nov  1 12:42 modules.pcimap
-rw-r--r-- 1 root root   43 Nov  1 12:42 modules.seriomap
-rw-r--r-- 1 root root 1801 Nov  1 12:42 modules.symbols
-rw-r--r-- 1 root root  189 Nov  1 12:42 modules.usbmap
lrwxrwxrwx 1 root root   30 Oct 31 16:11 source -> /usr/src/zhk/linux-2.6.21.2zhk
(4)可以看出bulid和source都是软连接,build就是编译目录,source是内核源码所在目录。他们都依靠一个软连接,链接到/lib/modules/2.6.21.2目录下的

2. Linux下的一个很好的内存泄漏检测工具 调不尽的内存泄露,用不完的Valgrind
(一个介绍程序调试的精彩讲解:http://www.ibm.com/developerworks/cn/linux/l-pow-debug/)

Valgrind 介绍

Valgrind是一个GPL的软件,用于Linux(For x86, amd64 and ppc32)程序的内存调试和代码剖析。你可以在它的环境中运行你的程序来监视内存的使用情况,比如C 语言中的malloc和free或者 C++中的new和 delete。使用Valgrind的工具包,你可以自动的检测许多内存管理和线程的bug,避免花费太多的时间在bug寻找上,使得你的程序更加稳固。

Valgrind的主要功能

Valgrind工具包包含多个工具,如Memcheck,Cachegrind,Helgrind, Callgrind,Massif。下面分别介绍个工具的作用:

Memcheck 工具主要检查下面的程序错误:

  • 使用未初始化的内存 (Use of uninitialised memory)
  • 使用已经释放了的内存 (Reading/writing memory after it has been free’d)
  • 使用超过 malloc分配的内存空间(Reading/writing off the end of malloc’d blocks)
  • 对堆栈的非法访问 (Reading/writing inappropriate areas on the stack)
  • 申请的空间是否有释放 (Memory leaks – where pointers to malloc’d blocks are lost forever)
  • malloc/free/new/delete申请和释放内存的匹配(Mismatched use of malloc/new/new [] vs free/delete/delete [])
  • src和dst的重叠(Overlapping src and dst pointers in memcpy() and related functions)

Callgrind

Callgrind收集程序运行时的一些数据,函数调用关系等信息,还可以有选择地进行cache 模拟。在运行结束时,它会把分析数据写入一个文件。callgrind_annotate可以把这个文件的内容转化成可读的形式。

Cachegrind

它模拟 CPU中的一级缓存I1,D1和L2二级缓存,能够精确地指出程序中 cache的丢失和命中。如果需要,它还能够为我们提供cache丢失次数,内存引用次数,以及每行代码,每个函数,每个模块,整个程序产生的指令数。这对优化程序有很大的帮助。

Helgrind

它主要用来检查多线程程序中出现的竞争问题。Helgrind 寻找内存中被多个线程访问,而又没有一贯加锁的区域,这些区域往往是线程之间失去同步的地方,而且会导致难以发掘的错误。Helgrind实现了名为” Eraser” 的竞争检测算法,并做了进一步改进,减少了报告错误的次数。

Massif

堆栈分析器,它能测量程序在堆栈中使用了多少内存,告诉我们堆块,堆管理块和栈的大小。Massif能帮助我们减少内存的使用,在带有虚拟内存的现代系统中,它还能够加速我们程序的运行,减少程序停留在交换区中的几率。

Valgrind 安装

1、 到www.valgrind.org下载最新版valgrind-3.2.3.tar.bz2
2、 解压安装包:tar –jxvf valgrind-3.2.3.tar.bz2
3、 解压后生成目录valgrind-3.2.3
4、 cd valgrind-3.2.3
5、 ./configure
6、 Make;make install

Valgrind 使用

用法: valgrind [options] prog-and-args [options]: 常用选项,适用于所有Valgrind工具

  1. -tool=<name> 最常用的选项。运行 valgrind中名为toolname的工具。默认memcheck。
  2. h –help 显示帮助信息。
  3. -version 显示 valgrind内核的版本,每个工具都有各自的版本。
  4. q –quiet 安静地运行,只打印错误信息。
  5. v –verbose 更详细的信息, 增加错误数统计。
  6. -trace-children=no|yes 跟踪子线程? [no]
  7. -track-fds=no|yes 跟踪打开的文件描述?[no]
  8. -time-stamp=no|yes 增加时间戳到LOG信息? [no]
  9. -log-fd=<number> 输出LOG到描述符文件 [2=stderr]
  10. -log-file=<file> 将输出的信息写入到filename.PID的文件里,PID是运行程序的进行ID
  11. -log-file-exactly=<file> 输出LOG信息到 file
  12. -log-file-qualifier=<VAR> 取得环境变量的值来做为输出信息的文件名。 [none]
  13. -log-socket=ipaddr:port 输出LOG到socket ,ipaddr:port

LOG信息输出

  1. -xml=yes 将信息以xml格式输出,只有memcheck可用
  2. -num-callers=<number> show <number> callers in stack traces [12]
  3. -error-limit=no|yes 如果太多错误,则停止显示新错误? [yes]
  4. -error-exitcode=<number> 如果发现错误则返回错误代码 [0=disable]
  5. -db-attach=no|yes 当出现错误, valgrind会自动启动调试器gdb。[no]
  6. -db-command=<command> 启动调试器的命令行选项[gdb -nw %f %p]

适用于Memcheck工具的相关选项:

  1. -leak-check=no|summary|full 要求对leak给出详细信息? [summary]
  2. -leak-resolution=low|med|high how much bt merging in leak check [low]
  3. -show-reachable=no|yes show reachable blocks in leak check? [no]

Valgrind 使用举例

下面是一段有问题的C程序代码test.c

#include <stdlib.h>
void f(void)
{
int* x = malloc(10 * sizeof(int));
x[10] = 0; //问题1: 数组下标越界
} //问题2: 内存没有释放
int main(void)
{
f();
return 0;
}
1、 编译程序test.c
gcc -Wall test.c -g -o test
2、 使用Valgrind检查程序BUG
valgrind --tool=memcheck --leak-check=full ./test
3、 分析输出的调试信息
==3908== Memcheck, a memory error detector.
==3908== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==3908== Using LibVEX rev 1732, a library for dynamic binary translation.
==3908== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==3908== Using valgrind-3.2.3, a dynamic binary instrumentation framework.
==3908== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==3908== For more details, rerun with: -v
==3908==
--3908-- DWARF2 CFI reader: unhandled CFI instruction 0:50
--3908-- DWARF2 CFI reader: unhandled CFI instruction 0:50
/*数组越界错误*/
==3908== Invalid write of size 4
==3908== at 0x8048384: f (test.c:6)
==3908== by 0x80483AC: main (test.c:11)
==3908== Address 0x400C050 is 0 bytes after a block of size 40 alloc'd
==3908== at 0x40046F2: malloc (vg_replace_malloc.c:149)
==3908== by 0x8048377: f (test.c:5)
==3908== by 0x80483AC: main (test.c:11)
==3908==
==3908== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 14 from 1)
==3908== malloc/free: in use at exit: 40 bytes in 1 blocks.
==3908== malloc/free: 1 allocs, 0 frees, 40 bytes allocated.
==3908== For counts of detected errors, rerun with: -v
==3908== searching for pointers to 1 not-freed blocks.
==3908== checked 59,124 bytes.
==3908==
==3908==
/*有内存空间没有释放*/
==3908== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==3908== at 0x40046F2: malloc (vg_replace_malloc.c:149)
==3908== by 0x8048377: f (test.c:5)
==3908== by 0x80483AC: main (test.c:11)
==3908==
==3908== LEAK SUMMARY:
==3908== definitely lost: 40 bytes in 1 blocks.
==3908== possibly lost: 0 bytes in 0 blocks.
==3908== still reachable: 0 bytes in 0 blocks.
==3908== suppressed: 0 bytes in 0 blocks.
3.dd 命令
  

The basic command is structured as follows:
dd if=<source> of=<target> bs=<byte size>(some power of 2, not less than 512 bytes(ie, 512, 1024, 2048, 4096, 8192, 16384) conv=<conversion>.
Source is the data being read. Target is where the data gets written. If you mess up, and accidently reverse the source and target, you can wipe out a lot of data.

Examples::

Copy one hard disk partition to another hard disk:

dd if=/dev/sda2 of=/dev/sdb2 bs=4096 conv=notrunc,noerror

sda2, sdb2 are partitions. You want to copy sda2 to sdb2. If sdb2 doesn't exist, dd will start at the beginning of the disk, and create it. Be careful with order of if and of. You can write a blank disk to a good disk if you get confused.

Make an iso image of a CD:

dd if=/dev/hdc of=/home/sam/mycd.iso bs=2048 conv=notrunc

CD sectors are 2048 bytes, so this copies sector for sector. The result will be a hard disk image file of the CD. You can use "chmod a+rwx mycd.iso" to make the image writable. You can mount the image with "mkdir /mnt/mycd", this line in fstab: "/home/sam/mycd.iso /mnt/mycd iso9660 rw,user,noauto 0 0", save fstab, "mount -o loop /mnt/mycd". Then the file system will be viewable as files and directories in the directory /mnt/mycd. You can edit the image as you wish, and the new file will be "/home/sam/mycd.iso" dd does not write to CD's. You need to use a burning utility, or the cdrdao command

 

Copy a floppy disk:

dd if=/dev/fd0 of=/home/sam/floppy.image bs=2x80x18b conv=notrunc

The 18b specifies 18 sectors of 512 bytes, the 2x multiplies the sector size by the number of heads, and the 80x is for the cylinders--a total of 1474560 bytes. This issues a single 1474560-byte read request to /dev/fd0 and a single 1474560 write request to /tmp/floppy.image. This makes a hard drive image of the floppy, with bootable info intact.

Copy a hard drive image of a floppy to a floppy:

dd if=/home/sam/floppy.image of=fd0 bs=2x80x18b conv=notrunc

Copy just the MBR and boot sector of a floppy to hard drive image:

dd if=/dev/fd0 of=/home/sam/MBRboot.image bs=512 count=2

This copies the first 2 sectors of the floppy

Cloning an entire hard disk:

dd if=/dev/sda of=/dev/sdb conv=notrunc,noerror

in this example, sda is the source. sdb is the target. Do not reverse the intended source and target. Surprisingly many people do. notrunc means to not truncate. noerror means to keep going if there is an error. Normally dd stops at any error. if you have a question about a hard drive on whether or not it works, you can try to use it as the source drive for the dd command. You should get an error if it is not working. target drives need to be really messed up to give an error in dd.

Copy MBR only of a hard drive:

dd if=/dev/sda of=/home/sam/MBR.image bs=446 count=1

this will copy the first 446 bytes of the hard drive to a file. If you haven't already guessed, reversing the objects of if and of, in the dd command line reverses the direction of the write.

Wipe a hard drive of all data (you would want to boot from a cd to do this)
http://www.efense.com/helix is a good boot cd

the helix boot environment contains the DoD version of dd called dcfldd. It works the same way, but is has a progress bar.

dd if=/dev/zero of=/dev/sda conv=notrunc

This is useful for getting rid of viruses, DRM trojans and the like.

It would be useful, at this time to interject a tip:

I have several machines, but on the one I use a lot I have two SATA hard drives. They are exactly the same. Before I do anything dangerous, I boot from the helix CD, run

dcfldd if=/dev/sda of=/dev/sdb bs=4096 conv=notrunc,noerror

and copy my present working sda drive system to the sdb drive. If I wreck the installation on sda, I just boot with the helix cd and

dcfldd if=/dev/sdb of=/dev/sda bs=4096 conv=notrunc,noerror

Please note: bs=4096 works fast for machines with at least 128 MB of ram. dd uses a lot of buffers. At bs=4096, on modern machines, the optimal transfer rate is reached for hard drives.

To make a file of 100 random bytes

dd if=/dev/urandom of=/home/sam/myrandom bs=1 count=100

Here, urandom is the linux random byte device. myrandom is a file. Byte size equals 1 and there are 100 of them. Gpg requires a random seed to generate keys. Generating a file of say 4096 random bytes, which can be passed to Gpg, will allow a truly random seed.

Write random data over a file before deleting it:
first do an ls -l to find filesize. In this case it is 3769

ls -l afile
-rw------- ... 3769 Nov 2 13:41 <filename>
dd if=/dev/urandom of=<filename> / bs=3769 count=1 conv=notrunc

This will write random characters over the entire file.

Copy a disk partition to a file on a different partition. Do not copy a partition to the same partition.

dd if=/dev/sdb2 of=/home/sam/partition.image bs=4096 conv=notrunc,noerror

This will make a file that is an exact duplicate of the sdb2 partition. You can substitue hdb, sda, hda, or whatever the disk is called.

Restore a disk partition from an image file.

dd if=/home/sam/partition.image of=/dev/sdb2 bs=4096 conv=notrunc,noerror

This way you can get a bazonga hard drive and partition it so you can back up your root partition. If you mess up your root partition, you just boot from the helix cd and restore the image.

To covert a file to all uppercase:

dd if=filename of=filename conv=ucase

Copy ram memory to a file:

dd if=/dev/mem of=/home/sam/mem.bin bs=1024

The device /dev/mem is your system memory. You can actually copy any blobk or character device to a file with dd. Memory capture on a fast system, with bs=1024 takes about 60 seconds. Copying a 120 GB HDD takes about an hour. Copying a CD to hard drive takes about 10 minutes. Copying a floppy to a hard drive takes about 2 minutes. With dd, your floppy drive images will not change at all. If you have a bootable DOS diskette, and you save it to your HDD as an image file, when you restore that image to another floppy it will be bootable. dd is an excellent way to make an image of MS Windows XP install CD's. When you make a copy of such a cd, there is one sector that is of nonstandard length. It is the last sector. dd doesn't pad this sector, making the copy indistinguishable from the original. If you burn the CD using cdrdao, the resulting disk will be an absolutely exact copy of the original.

 

4.crontab

crontab命令的功能是在一定的时间间隔调度一些命令的执行。在/etc目录下有一个crontab文件,这里存放有系统运行的一些调度程序。每个用户可以建立自己的调度crontab。

crontab命令有三种形式的命令行结构:

crontab [-u user] [file]

crontab [-u user] [-e|-l|-r]

crontab -l -u [-e|-l|-r] 第一个命令行中,file是命令文件的名字。如果在命令行中指定了这个文件,那么执行crontab命令,则将这个文件拷贝到crontabs目录下;如果在命令行中没有制定这个文件,crontab命令将接受标准输入(键盘)上键入的命令,并将他们也存放在crontab目录下。

命令行中-r选项的作用是从/usr/spool/cron/crontabs目录下删除用户定义的文件crontab;

命令行中-l选项的作用是显示用户crontab文件的内容。

使用命令crontab -u user -e命令编辑用户user的cron(c)作业。用户通过编辑文件来增加或修改任何作业请求。

执行命令crontab -u user -r即可删除当前用户的所有的cron作业。

作业与它们预定的时间储存在文件/usr/spool/cron/crontabs/username里。username使用户名,在相应的文件中存放着该用户所要运行的命令。命令执行的结果,无论是标准输出还是错误输出,都将以邮件形式发给用户。文件里的每一个请求必须包含以spaces和tabs分割的六个域。前五个字段可以取整数值,指定何时开始工作,第六个域是字符串,称为命令字段,其中包括了crontab调度执行的命令。

第一道第五个字段的整数取值范围及意义是:

0~59 表示分

1~23 表示小时

1~31 表示日

1~12 表示月份

0~6 表示星期(其中0表示星期日)

/usr/lib/cron/cron.allow表示谁能使用crontab命令。如果它是一个空文件表明没有一个用户能安排作业。如果这个文件不存在,而有另外一个文件/usr/lib/cron/cron.deny,则只有不包括在这个文件中的用户才可以使用crontab命令。如果它是一个空文件表明任何用户都可安排作业。两个文件同时存在时cron.allow优先,如果都不存在,只有超级用户可以安排作业。
然关于 Crontab 的介绍到处都是,详细读了一遍这个词条,收获还是有的。Crontab 这个名字来自 "chronos",一个古希腊语, “时间”的意思.

常见陷阱

每个SA、DBA 或者是普通的 Unix 用户,在第一次使用 Crontab 的时候都会遇到问题. 运行 Crontab 的常见错误包括如下几种:

1) 出于测试目的新创建了一条 Cron JOB, 时间间隔必须超过两分钟,否则 JOB 将调度不到。如果必须忽略这两分钟的载入配置时间差,可以通过重新启动 Cron Daemon 做到。

2) 从 Crontab 中启动 X Window 程序需要注意的事项:所以要么在程序前初始化 "DISPLAY=:0.0", 要么在应用程序后面追加参数 --display :0.0

3) 命令中的 % 必须做转义处理: /% .我个人的意见是不要在命令行里带这个参数,干脆写到脚本里,然后调度该脚本即可。

其实我倒是认为使用 Crontab 最常见的一个问题往往是因为环境变量不对。经常会看到论坛里有人问:为什么我的 Crontab 创建了不执行? 准备创建一条 Cron JOB 的时候,很多人都喜欢在命令行下运行一遍,因为这个时候环境变量是随着 Shell 自动带进来,在 Crontab 中则可能因为找不到正确的环境变量,JOB 就不能执行。这个小问题就像出天花,一次教训之后就都记得了。

必须使用的一则技巧

每条 JOB 执行完毕之后,系统会自动将输出发送邮件给当前系统用户。日积月累,非常的多,甚至会撑爆整个系统。所以每条 JOB 命令后面进行重定向处理是非常必要的: >/dev/null 2>&1 。前提是对 Job 中的命令需要正常输出已经作了一定的处理, 比如追加到某个特定日志文件。

附: Crontab 的格式说明如下:

* 逗号(',') 指定列表值。如: "1,3,4,7,8"
* 中横线('-') 指定范围值 如 "1-6", 代表 "1,2,3,4,5,6"
* 星号 ('*') 代表所有可能的值

Linux(开源系统似乎都可以)下还有个 "/" 可以用. 在 Minute 字段上,*/15 表示每 15 分钟执行一次. 而这个特性在商业 Unix ,比如 AIX 上就没有.

    
# Use the hash sign to prefix a comment
+----------------  minute ( 0   -   59 )
|    +-------------  hour ( 0   -   23 )
|    |    +----------  day of month ( 1   -   31 )
|    |    |    +-------  month ( 1   -   12 )
|    |    |    |    +----  day of week ( 0   -   7 ) (Sunday = 0  or  7 )
|    |    |    |    |
*    *    *    *    *   command to be executed
5./dev/null 与 /dev/zero区别
dev/null,外号叫无底洞,你可以向它输出任何数据,它通吃,并且不会撑着!
/dev/zero,是一个输入设备,你可你用它来初始化文件
/dev/null------它是空设备,也称为位桶(bit bucket)。任何写入它的输出都会被抛弃。如果不想让消息以标准输出显示或写入文件,那么可以将消息重定向到位桶。
/dev/zero------该设备无穷尽地提供0,可以使用任何你需要的数目——设备提供的要多的多。他可以用于向设备或文件写入字符串0。
dd if=/dev/zero of=./test.txt bs=1k count=1 创建一个1K的文件test.txt
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值