如何写论文?写好论文?免费论文网提供各类免费论文写作素材!
当前位置:免费论文网 > 美文好词 > 优质好文 > linux机器码

linux机器码

来源:免费论文网 | 时间:2018-11-08 14:56 | 移动端:linux机器码

篇一:linux系统调试工具GDB 命令详细解释

Linux中包含有一个很有用的调试工具--gdb(GNU Debuger),它可以用来调试C和C++程序,功能不亚于Windows下的许多图形界面的调试工具。

和所有常用的调试工具一样,gdb提供了以下功能:

# 监视程序中变量的值

# 在程序中设置断点

# 程序的单步执行

在使用gdb前,必须先载入可执行文件,因为要进行调试,文件中就必须包含调试信息,所以在用gcc或cc编译时就需要用-g参数来打开程序的调试选项。

调试开始时,必须先载入要进行调试的程序,可以用以下两种方式:

* 在启动gdb后执行以下命令:

file 可执行文件路径

* 在gdb启动时就载入程序:

gdb 可执行文件路径

载入程序后,接下来就是要进行断点的设置,要监视的变量的添加等工作,下面对在这个过程中常会用到的命令逐一进行介绍:

* list :显示程序中的代码,常用使用格式有:

list

输出从上次调用list命令开始往后的10行程序代码。

list -

输出从上次调用list命令开始往前的10行程序代码。

list n

输出第n行附近的10行程序代码。

list function

输出函数function前后的10行程序代码。

* forward/search :从当前行向后查找匹配某个字符串的程序行。使用格式: forward/search 字符串

查找到的行号将保存在$_变量中,可以用print $_命令来查看。

* reverse-search :和forward/search相反,向前查找字符串。使用格式同上。 * break :在程序中设置断点,当程序运行到指定行上时,会暂停执行。使用格式: break 要设置断点的行号

* tbreak :设置临时断点,在设置之后只起作用一次。使用格式:

tbreak 要设置临时断点的行号

* clear :和break相反,clear用于清除断点。使用格式:

clear 要清除的断点所在的行号

* run :启动程序,在run后面带上参数可以传递给正在调试的程序。

* awatch :用来增加一个观察点(add watch),使用格式:

awatch 变量或表达式

当表达式的值发生改变或表达式的值被读取时,程序就会停止运行。

* watch :与awatch类似用来设置观察点,但程序只有当表达式的值发生改变时才会停止运行。使用格 式:

watch 变量或表达式

需要注意的是,awatch和watch都必须在程序运行的过程中设置观察点,即可运行run之后才能设置。

* commands :设置在遇到断点后执行特定的指令。使用格式有:

commands

设置遇到最后一个遇到的断点时要执行的命令

commands n

设置遇到断点号n时要执行的命令

注意,commands后面跟的是断点号,而不是断点所在的行号。

在输入命令后,就可以输入遇到断点后要执行的命令,每行一条命令,在输入最后一条命令后输入end就可以结束输入。

* delete :清除断点或自动显示的表达式。使用格式:

delete 断点号

* disable :让指定断点失效。使用格式:

disable 断点号列表

断点号之间用空格间隔开。

* enable :和disable相反,恢复失效的断点。使用格式:

enable 断点编号列表

* ignore :忽略断点。使用格式:

ignore 断点号 忽略次数

* condition :设置断点在一定条件下才能生效。使用格式:

condition 断点号 条件表达式

* cont/continue :使程序在暂停在断点之后继续运行。使用格式:

cont

跳过当前断点继续运行。

cont n

跳过n次断点,继续运行。

当n为1时,cont 1即为cont。

* jump :让程序跳到指定行开始调试。使用格式:

jump 行号

* next :继续执行语句,但是跳过子程序的调用。使用格式:

next

执行一条语句

next n

执行n条语句

* nexti :单步执行语句,但和next不同的是,它会跟踪到子程序的内部,但不打印出子程序内部的语句。使用格式同上。

* step :与next类似,但是它会跟踪到子程序的内部,而且会显示子程序内部的执行情况。使用格式同上。

* stepi :与step类似,但是比step更详细,是nexti和step的结合。使用格式同上。 * whatis :显示某个变量或表达式的数据类型。使用格式:

whatis 变量或表达式

* ptype :和whatis类似,用于显示数据类型,但是它还可以显示typedef定义的类型等。使用格式:

ptype 变量或表达式

* set :设置程序中变量的值。使用格式:

set 变量=表达式

set 变量:=表达式

* display :增加要显示值的表达式。使用格式:

display 表达式

* info display :显示当前所有的要显示值的表达式。

* delete display/undisplay :删除要显示值的表达式。使用格式:

delete display/undisplay 表达式编号

* disable display :暂时不显示一个要表达式的值。使用格式:

disable display 表达式编号

* enable display :与disable display相反,使用表达式恢复显示。使用格式: enable display 表达式编号

* print :打印变量或表达式的值。使用格式:

print 变量或表达式

表达式中有两个符号有特殊含义:$和$$。

$表示给定序号的前一个序号,$$表示给定序号的前两个序号。

如果$和$$后面不带数字,则给定序号为当前序号。

* backtrace :打印指定个数的栈帧(stack frame)。使用格式:

backtrace 栈帧个数

* frame :打印栈帧。使用格式:

frame 栈帧号

* info frame :显示当前栈帧的详细信息。

* select-frame :选择栈帧,选择后可以用info frame来显示栈帧信息。使用格式: select-frame 栈帧号

* kill :结束当前程序的调试。

* quit :退出gdb。

如要查看所有的gdb命令,可以在gdb下键入两次Tab(制表符),运行“help command”可以查看命令command的详细使用格式。

本文仅对使用gdb调试过程中的一些常用指令的用法进行简单地总结,如要获取关于gdb的更详细的资料,请参阅gdb的官方文档:

http://www.gnu.org/software/gdb/documentation/

gdb 命令大全

1. 启动

gdb 应用程序名

gdb 应用程序名 core文件名

gdb 应用程序名 pid

gdb --args 应用程序名 应用程序的运行参数

帮助:

help 显示帮助

info 显示程序状态

set 修改

show 显示gdb状态

运行及运行环境设置:

set args #设置运行参数

show args#显示运行参数

set env 变量名 = 值 #设置环境变量

unset env [变量名]#取消环境变量

show env [变量名]#显示环境变量

path 目录名 #把目录添加到查找路径中

show paths #显示当前查找路径

cd 目录 #切换工作目录

pwd#显示当前工作目录

tty /dev/pts/1 #修改程序的输入输出到指定的tty set inferior-tty /dev/pts/1 #修改程序的输出到指定的tty

show inferior-tty

show tty

run 参数 #运行

start 参数 #开始运行,但是会在main函数停止

attach pid

detach

kill #退出

Ctrl-C#中断(SIGINT)

Ctrl-]

线程操作:

info threads #查看所有线程信息

thread 线程id #切换到指定线程

thread apply [threadno | all ] 参数 #对所有线程都应用某个命令 子进程调试:

set follow-fork-mode child|parent#fork后,需要跟踪谁

篇二:Linux之GCC经典教程之一

Linux之GCC经典教程

准备工作

注意:本文可能会让你失望,如果你有下列疑问的话:为什么要在终端输命令啊? GCC 是什么东西,怎么在菜单中找不到? GCC 不能有像 VC 那样的窗口吗?…… 那么你真正想要了解的可能是 anjuta,kdevelop,geany,code blocks,eclipse,netbeans 等 IDE 集成开发环境。即使在这种情况下,由于 GCC 是以上 IDE 的后台的编译器,本文仍值得你稍作了解。

如果你还没装编译环境或自己不确定装没装,不妨先执行

sudo apt-get install build-essential

如果你需要编译 Fortran 程序,那么还需要安装 gfortran(或 g77) sudo apt-get install gfortran

编译简单的 C 程序

C 语言经典的入门例子是 Hello World,下面是一示例代码: #include <stdio.h>

int main(void)

{

printf(“Hello, world!n”);

return 0;

}

我们假定该代码存为文件?hello.c?。要用 gcc 编译该文件,使用下面的命令: $ gcc -g -Wall hello.c -o hello

该命令将文件?hello.c?中的代码编译为机器码并存储在可执行文件 ?hello?中。机器码的文件名是通过 -o 选项指定的。该选项通常作为命令行中的最后一个参数。如果被省略,输出文件默认为 ?a.out?。

注意到如果当前目录中与可执行文件重名的文件已经存在,它将被覆盖。

选项 -Wall 开启编译器几乎所有常用的警告──强烈建议你始终使用该选项。编译器有很多其他的警告选项,但 -Wall 是最常用的。默认情况下GCC 不会产生任何警告信息。当编写 C 或 C++ 程序时编译器警告非常有助于检测程序存在的问题。 注意如果有用到math.h库等非gcc默认调用的标准库,请使用-lm参数 本例中,编译器使用了 -Wall 选项而没产生任何警告,因为示例程序是完全合法的。

选项 “”-g”" 表示在生成的目标文件中带调试信息,调试信息可以在程序异常中止产生core后,帮助分析错误产生的源头,包括产生错误的文件名和行号等非常多有用的信息。

要运行该程序,输入可执行文件的路径如下:

$ ./hello

Hello, world!

这将可执行文件载入内存,并使 CPU 开始执行其包含的指令。 路径 ./ 指代当前目录,因此 ./hello 载入并执行当前目录下的可执行文件 ?hello?。

捕捉错误

如上所述,当用 C 或 C++ 编程时,编译器警告是非常重要的助手。为了说明这一点,下面的例子包含一个微妙的错误:为一个整数值错误地指定了一浮点数控制符?%f?。

#include <stdio.h>

int main (void)

{

printf (“Two plus two is %fn”, 4);

return 0;

}

一眼看去该错误并不明显,但是它可被编译器捕捉到,只要启用了警告选项 -Wall。 编译上面的程序?bad.c?,将得到如下的消息:

$ gcc -Wall -o bad bad.c

main.c: 在函数?main?中:

main.c:5: 警告: 格式?%f?需要类型?double?,但实参 2 的类型为?int?

这表明文件 ?bad.c?第 6 行中的格式字符串用法不正确。GCC 的消息总是具有下面的格式 文件名:行号:消息。编译器对错误与警告区别对待,前者将阻止编译,后者表明可能存在的问题但并不阻止程序编译。

本例中,对整数值来说,正确的格式控制符应该是 %d。

如果不启用 -Wall,程序表面看起来编译正常,但是会产生不正确的结果: $ gcc bad.c -o bad

$ ./bad

Two plus two is 0.000000

显而易见,开发程序时不检查警告是非常危险的。如果有函数使用不当,将可能导致程序崩溃或产生错误的结果。开启编译器警告选项 -Wall 可捕捉 C 编程时的多数常见错误。

编译多个源文件

一个源程序可以分成几个文件。这样便于编辑与理解,尤其是程序非常大的时候。这也使各部分独立编译成为可能。

下面的例子中我们将程序 Hello World 分割成 3 个文件:?hello.c?,?hello_fn.c?和头文件?hello.h?。这是主程序?hello.c?:

#include “hello.h”

int main(void)

{

hello (“world”);

return 0;

}

在先前例子的?hello.c?中,我们调用的是库函数 printf,本例中我们用一个定义在文件?hello_fn.c?中的函数 hello 取代它。

主程序中包含有头文件?hello.h?,该头文件包含函数 hello 的声明。我们不需要在?hello.c?文件中包含系统头文件?stdio.h?来声明函数 printf,因为?hello.c?没有直接调用 printf。

文件?hello.h?中的声明只用了一行就指定了函数 hello 的原型。

void hello (const char * name);

函数 hello 的定义在文件?hello_fn.c?中:

#include <stdio.h>

#include “hello.h”

void hello (const char * name)

{

printf (“Hello, %s!n”, name);

}

语句 #include “FILE.h” 与 #include <FILE.h> 有所不同:前者在搜索系统头文件目录之前将先在当前目录中搜索文件?FILE.h?,后者只搜索系统头文件而不查看当前目录。

要用gcc编译以上源文件,使用下面的命令:

$ gcc -Wall hello.c hello_fn.c -o newhello

本例中,我们使用选项 -o 为可执行文件指定了一个不同的名字 newhello。注意到头文件?hello.h?并未在命令行中指定。源文件中的的 #include “hello.h” 指示符使得编译器自动将其包含到合适的位置。

要运行本程序,输入可执行文件的路径名:

$ ./newhello

Hello, world!

源程序各部分被编译为单一的可执行文件,它与我们先前的例子产生的结果相同。 简单的 Makefile 文件

为便于不熟悉 make 的读者理解,本节提供一个简单的用法示例。Make 凭借本身的优势,可在所有的 Unix 系统中被找到。要了解关于Gnu make 的更多信息,请参考 Richard M. Stallman 和 Roland McGrath 编写的 GNU Make 手册。 Make 从 makefile(默认是当前目录下的名为?Makefile?的文件)中读取项目的描述。makefile指定了一系列目标(比如可执行文件)和依赖(比如对象文件和源文件)的编译规则,其格式如下:

目标: 依赖

命令

对每一个目标,make 检查其对应的依赖文件修改时间来确定该目标是否需要利用对应的命令重新建立。注意到,makefile 中命令行必须以单个的 TAB 字符进行缩进,不能是空格。

GNU Make 包含许多默认的规则(参考隐含规则)来简化 makefile 的构建。比如说,它们指定?.o?文件可以通过编译?.c?文件得到,可执行文件可以通过将?.o?链接到一起获得。隐含规则通过被叫做make变量的东西所指定,比如 CC(C 语言编译器)和 CFLAGS(C程序的编译选项);在makefile文件中它们通过独占一行的 变量=值 的形式被设置。对 C++ ,其等价的变量是CXX和CXXFLAGS,而变量CPPFLAGS则是编译预处理选项。

现在我们为上一节的项目写一个简单的 makefile 文件:

CC=gcc

CFLAGS=-Wall

hello: hello.o hello_fn.o

clean:

rm -f hello hello.o hello_fn.o

该文件可以这样来读:使用 C 语言编译器 gcc,和编译选项?-Wall?,从对象文件?hello.o?和?hello_fn.o?生成目标可执行文件 hello(文件?hello.o?和?hello_fn.o?通过隐含规则分别由?hello.c?和?hello_fn.c?生成)。目标clean没有依赖文件,它只是简单地移除所有编译生成的文件。rm命令的选项 ?-f?(force) 抑制文件不存在时产生的错误消息。

另外,需要注意的是,如果包含main函数的cpp文件为A.cpp, makefile中最好把可执行文件名也写成 A。

要使用该 makefile 文件,输入 make。不加参数调用make时,makefile文件中的第一个目标被建立,从而生成可执行文件?hello?:

$ make

gcc -Wall -c -o hello.o hello.c

gcc -Wall -c -o hello_fn.o hello_fn.c

gcc hello.o hello_fn.o -o hello

$ ./hello

Hello, world!

篇三:深入浅出Linux工具与编程

? 初级部分和高级部分

? 初级部分包括:Linux操作系统介绍、Linux命令说明、Linux常见实用工具(正则表

达式、find、sed、awk)、Shell编程、Linux C语言程序设计、Linux C语言开发工具

(vi与vim编辑器、gcc、Makefile和gdb);

? 高级部分包括:Linux进程编程

? (Linux进程、Linux线程、管道与信号、消息队列、信号量和共享内存)、Linux文

件编程、网络编程和XML编程。

Linux的重要概念

1. 机器指令、程序、

2. 进程、(程序、线程)

3. 中断、

4. 文件系统、文件、文件名

5. 目录、

6. 相对路径、绝对路径、

7. inode节点

Linux组成

1. shell

用户与内核进行交互操作的一种接口

2. 文件系统

文件系统不仅包含着文件中的数据而且还有文件系统的结构

3. 内核

进程调度、内存管理、虚拟文件系统、网络接口、进程间通信。

4. 实用工具

压缩、解压工具、shell工具。

linux内核由5个模块构成:进度调度模块、内存管理模块、文件系统模块、进程间通信模块和网络接口模块。

linux下用户分为三类:

? 超级用户: 户名为root,拥有一切权限。

? 系统用户:linux系统正常工作必须的内建用户,主要为了满足系统进程对文件属主的

要求而建立的,系统用户不能用来登陆。

? 普通用户:为了让使用者能够使用linux系统资源而建立的。

Linux文件管理

?

?

?

?

?

?

?

?

? linux一切皆为文件: d:目录文件 l: 符号链接(指向另一个文件) b:块设备文件 c: 字符设备文件 p: 命名管道文件 s: 套接字文件 -: 普通文件 文件属性通常由10位,第1位为文件类型,第2-4位为该文件用户权限,第5-7位为

该组用户权限,第8-10位为其他用户权限。

例如:某文件属性为-rwxrw-r--

正则表达式

? Shell: “外壳”,交互编程接口,也是一个命令解释器,可以用shell编写各种脚本工

具。

? 解释型语言,边识别翻译边执行,不会生成2进制机器码,

? shell执行的流程就是shell解释器顺序读取每一行命令,识别成一条条的Linux系统

指令,然后调用Linux相应命令接口执行结果。

shell脚本的三种类型:

? Bourne Shell (B Shell)

? Korn Shell

? C Shell

Shell 脚本头文件头可用#!/bin/sh说明脚本用哪一种Shell执行,#!表示使用哪一种解释器执行当前文本,/bin/sh指用B Shell

Shell 的注释通常以#开头

Shell中符号及意义

? * : 匹配0个或多个字符组成的串。

? ?:匹配单个字符

? [ ]: 匹配的字符范围和列表 $ls [a-c]*a~c

? $0 : 当前Shell名

? $: 引用某个变量$PWD

? #: 注释符号

? `...`: 命令替换,倒引号引起字符串作为Shell命令来执行。

Shell变量

变量特点

1. 无需定义可直接使用

2. Shell大小写敏感

3. $为Shell保留字符,变量被其他变量引用前面要加$。

4. 变量赋值“=”两边没有空格的,不然会出错。

5. 如果赋值语句中,右边没有任何信息,那么这个变量为一个空字符串;另外仅定义声明

而没有赋值的变量也是一个空字符串。

6. Shell只有两种类型,一种是整型数字,一种是字符串。

7. 如果一个变量中含空格、制表位、换行符,则要用双引号引起,不然会出错。

8. 字符串左右应加双引号“”。

9. Shell内置9个位置变量,$1~$9。

引用变量的三种方法

1. 使用双引号

“$var”

2. 使用大括号引用变量

{$var}

3. 直接引用变量

$var

用户变量赋值

1. 直接赋值

user=meng

null=

number=121313

2. 变量赋值

var1=$user

var2=$var1

read读入

read 变量1[变量2]

read var1 var2

read 变量1 [变量2]

1. 如果变量的个数多于输入字符串字符的个数,则依次赋值,剩下的变量取空值。

2. 如果变量的个数等于输入字符串的字符个数,则一一赋值。

3. 如果变量的个数小于输入字符串的字符个数,除依次赋值之外,最后一个变量接纳剩下

的所有字符串。

参数置换方式与变量赋值

? ${变量:-字串} 如果变量设定并非空,则返回的是变量的值,否则是字符串的值。 ? ${变量:+字串} 如果变量设定并非空,则返回的是变量的值,否则是变量的值。 ? ${变量:=字串} 如果变量设定并非空,则返回的是变量的值,否则是字符串的值,同

时变量被设成字符串。

? ${变量:?字串} 如果变量设定并非空,则返回的是变量的值,否则返回报错。

Shell退出状态:$?是一个Shell中的内置变量,代表着最后一个进行进程退出的状态码。 管道与信号是进程间通信的两种机制。

操作系统中每个管道有两个文件描述符,一个文件描述符用来读,另一个用来写。 进程间的通信六种:

1. 管道和命名管道。

2. 信号

3. 共享内存

4. 消息队列

5. 信号量

6. 套接字

进程间的通信目的: 数据传输、数据共享、通知事件、资源共享、进程控制

命名管道在使用时已经存在,用户可以打开或关闭管道。

匿名管道只在操作时存在,因而是临时对象。

信号是进程间通信机制中唯一的异步通信机制,可以看成异步通知,通知接该信号的进程有哪些事情发生。

同时是一种软件中断,当某进程接收到信号时,会中止目前的程序,去处理信号注册函数,然后回到断点继续往下执行。

信号发生的原因:硬件引起(按键或其他硬件故障)、软件引起kill ,raise,alarm,setitimer,等会引起信号的发送,或除以0会引起信号的发送。

处理信号的三种方式:

1. 忽略。

2. 设置相应的程序。软中断

3. 执行系统默认程序。

1. 忽略该信号。

2. 按系统默认方式处理。

3. 提供一个函数,信号发生时则调用该函数。

阻塞的信号

只能阻塞信号的处理,不会阻塞信号的发送。

从一个信号被递送给该进程到得到处理之间的时间为信号未决,或信号挂起,信号搁置。 一个进程应该包括:

程序的代码;

程序的数据; PC中的值,用来指示下一条将运行的指令;

一组通用的寄存器的当前值,堆、栈;

一组系统资源(如打开的文件)

总之,进程包含了正在运行的一个程序的所有状态信息。

进程状态的转换:

getpid()

getppid()

系统调用:系统调用把应用程序请求传给内核,调用相应的内核函数完成所需的处理。使应用程序由用户态进入核心态,系统调用有自己单独的堆栈空间。

库函数:存放在函数库中的函数,库函数具有明确的功能、入口调用参数和返回值,Linux库函数特指函数入口没有进行系统调用的库函数。库函数中常包含系统调用,库函数没有进行系统调用时,没有单独的堆栈空间。

用户态:进程的普通执行状态,只能执行规定的指令,不能执行特权指令。进程在用户态下只能访问该进程的存储空间,不能与系统硬件相互作用,不能访问系统资源,当它需要系统硬件资源时,会通过系统调用进入核心态。

核心态:能执行所有的机器指令,包括操作系统执行的特权指令,能访问所有的寄存器和存储区域,能直接控制所有系统资源和硬件资源。

Linux进程控制块(PCB)的作用:

Linux进程控制块是一个由结构体task_struct所定义的数据结构

操作系统利用PCB来控制和管理进程

? ID 0 调度进程,不执行任何磁盘上的程序,是内核的一部分。

? ID 1 init进程,读与系统有关的初始化文件,并将系统引导到一个状态,绝不会终止,

是一个普通用户进程,是所有孤儿进程的父进程。

wait与waitpid两函数

? 如果父进程的所有子进程还在运行,调用wait将使父进程阻塞,而调用waitpid时如

果options参数中指定WNOHANG,可以使父进程不阻塞而立刻返回0。

? wait等待第一个终止子进程,而waitpid函数可以通过pid参数指定等待哪一个子进程。 waitpid函数提供了wait函数没有提供三个功能?:

? 1、waitpid等待一个特定进程,而wait返回任一终止子进程状态。

? 2、waitpid提供一个wait非阻塞版本,有时希望取得一个子进程的状态,但不想进程

阻塞。

? 3、waitpid支持作业控制。


linux机器码》由:免费论文网互联网用户整理提供;
链接地址:http://www.csmayi.cn/meiwen/29098.html
转载请保留,谢谢!
相关文章