华南农业大学Linux课程实验七——Linux下C编程

题目一:gcc命令编译C程序生成可执行文件,gdb工具调试程序

在这里插入图片描述

解答

1、输入程序hostname.c。

#include <stdlib.h>//加上这个,避免在gcc -S时报错“warning: incompatible implicit declaration of built-in function ‘exit’”。
#include <sys/utsname.h>
#include <unistd.h>
#include <stdio.h>
int main()
{
        char computer[256];
        struct utsname uts;
        if(gethostname(computer,255)!=0 || uname(&uts) < 0){
                fprintf(stderr,"could not get host information\n");
                exit(1);
        }
        printf("computer host name is %s\n",computer);
        printf("system is %s on %s hardware\n",uts.sysname,uts.machine);
        printf("nodename is %s\n",uts.nodename);
        printf("version is %s,%s\n",uts.release,uts.version);
        exit(0);
}

2、生成可以用gdb调试的可执行文件hostname。

[root@wu1 test6]# ll
total 4
-rw-r--r-- 1 root root 484 May 14 11:20 hostname.c
[root@wu1 test6]# gcc -E hostname.c -o hostname.i
[root@wu1 test6]# gcc -S hostname.c -o hostname.s
[root@wu1 test6]# gcc hostname.c -o hostname
[root@wu1 test6]# ll
total 84
-rwxr-xr-x 1 root root  8616 May 14 11:26 hostname
-rw-r--r-- 1 root root   484 May 14 11:20 hostname.c
-rw-r--r-- 1 root root 62199 May 14 11:25 hostname.i
-rw-r--r-- 1 root root  1395 May 14 11:25 hostname.s

[root@wu1 test6]# gcc hostname.c -g -o hostname 	# 加上"-g"参数生成的可执行文件才能通过gdb调试
[root@wu1 test6]# ll
total 84
-rwxr-xr-x 1 root root 11144 May 15 13:36 hostname	# 文件变大了。
-rw-r--r-- 1 root root   484 May 14 11:20 hostname.c
-rw-r--r-- 1 root root 62199 May 14 11:25 hostname.i
-rw-r--r-- 1 root root  1395 May 14 11:25 hostname.s

[root@wu1 test6]# ./hostname	# 执行
computer host name is wu1
system is Linux on x86_64 hardware
nodename is wu1
version is 3.10.0-1062.18.1.el7.x86_64,#1 SMP Tue Mar 17 23:49:17 UTC 2020

下面这一小段不需要,只是记录下。

[root@wu1 test6]# file hostname
hostname: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=fa7c2a21544f44dba439c788457f2736fdd49aa0, not stripped
[root@wu1 test6]# yum install -y redhat-lsb
[root@wu1 test6]# lsb_release -a

3、gdb调试。

[root@wu1 test6]# yum -y install gdb
[root@wu1 test6]# gdb
GNU gdb (GDB) Red Hat Enterprise Linux 7.6.1-120.el7
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-redhat-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
(gdb) file hostname		# 指定需要进行调试的程序
Reading symbols from /root/test/test6/hostname...done.
(gdb) list	# 查看指定文件或者函数的源代码,并标出行号
1	#include <stdlib.h>
2	#include <sys/utsname.h>
3	#include <unistd.h>
4	#include <stdio.h>
5	int main()
6	{
7		char computer[256];
8		struct utsname uts;
9		if(gethostname(computer,255)!=0 || uname(&uts) < 0){
10			fprintf(stderr,"could not get host information\n");
(gdb) list
11			exit(1);
12		}
13		printf("computer host name is %s\n",computer);
14		printf("system is %s on %s hardware\n",uts.sysname,uts.machine);
15		printf("nodename is %s\n",uts.nodename);
16		printf("version is %s,%s\n",uts.release,uts.version);
17		exit(0);
18	}
(gdb) break 13	# 设置断点,程序执行到断点就会暂停起来
Breakpoint 1 at 0x4006fb: file hostname.c, line 13.
(gdb) break 16
Breakpoint 2 at 0x400758: file hostname.c, line 16.
(gdb) run	# 启动被执行的程序
Starting program: /root/test/test6/hostname 

Breakpoint 1, main () at hostname.c:13
13		printf("computer host name is %s\n",computer);
Missing separate debuginfos, use: debuginfo-install glibc-2.17-323.el7_9.x86_64
(gdb) next	# next/n单步(行)执行,如果遇到函数不会进入函数内部
computer host name is wu1
14		printf("system is %s on %s hardware\n",uts.sysname,uts.machine);
(gdb) continue	# 从一个断点继续执行到下一个断点
Continuing.
system is Linux on x86_64 hardware
nodename is wu1

Breakpoint 2, main () at hostname.c:16
16		printf("version is %s,%s\n",uts.release,uts.version);
(gdb) n
version is 3.10.0-1062.18.1.el7.x86_64,#1 SMP Tue Mar 17 23:49:17 UTC 2020
17		exit(0);
(gdb) n
[Inferior 1 (process 17363) exited normally]
(gdb) n
The program is not being run.
(gdb) q	# quit/q退出gdb调试环境

知识点

gdb常用的调试命令

命令含义
file指定需要进行调试的程序
list查看指定文件或者函数的源代码,并标出行号
break设置断点,程序执行到断点就会暂停起来
run启动被执行的程序
continue从一个断点继续执行到下一个断点
step单步(行)执行,如果遇到函数会进入函数内部
next/n单步(行)执行,如果遇到函数不会进入函数内部
print查看变量或者表达式的值
shell执行其后的shell命令
quit/q退出gdb调试环境

gdb一般的调试流程和例子

gdb一般的调试流程:file ->list ->break ->run ->step/next ->print ->quit
例子:
gcc -g sum.c -o sum-g	# 加了-g参数(gcc旁的那个)才可以调试
file sum-g
list
break 8		# 断点一
list
break 20	# 断点二
run
print result	# 目前在断点处停下了,看一下result这个变量的值
step	# 向下一步
next
n	# next命令的缩写
print sum		# 再看一下sum的值
n	# 这时因为代码已经结束了,所以输入next会报错
q	# 退出gdb

遇见的错误

1、

hostname.c:10:3: warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
   exit(1);
   ^
hostname.c:16:2: warning: incompatible implicit declaration of built-in function ‘exit’ [enabled by default]
  exit(0);

解决:warning: incompatible implicit declaration of built-in function ‘exit’_攻城狮的物联网基地-优快云博客

题目二:make和makefile

按照以下目录结构存放程序,然后制作makefile文件,请写出makefile文件内容并且画出依赖关系图。
在这里插入图片描述

现有一个程序由5个文件组成。

文件1:/main.c

#include "mytool1.h"
#include "mytool2.h"
int main()
{
	mytool1_print("hello mytool1!");
	mytool2_print("hello mytool2!");
	return 0;
}

文件2:/functions/mytool1.c

#include "mytool1.h"
#include <stdio.h>
void mytool1_print(char *print_str)
{
	printf("This is mytool1 print : %s ",print_str);
}

文件3:/functions/mytool1.h

#ifndef _MYTOOL_1_H
#define _MYTOOL_1_H
void mytool1_print(char *print_str);
#endif

文件4:/functions/mytool2.c

#include "mytool2.h"
#include <stdio.h>
void mytool2_print(char *print_str)
{
	printf("This is mytool2 print : %s ",print_str);
}

文件5:/functions/mytool2.h

#ifndef _MYTOOL_2_H
#define _MYTOOL_2_H
void mytool2_print(char *print_str);
#endif

解答

1、写出makefile文件并测试。

makefile文件

main : main.o mytool1.o mytool2.o
        gcc main.o mytool1.o mytool2.o -o main
main.o : main.c functions/mytool1.h functions/mytool2.h
        gcc -c main.c -I functions -o main.o
mytool1.o : functions/mytool1.c functions/mytool1.h
        gcc -c functions/mytool1.c -o mytool1.o
mytool2.o : functions/mytool2.c functions/mytool2.h
        gcc -c functions/mytool2.c -o mytool2.o
clean:
        rm -f *.o
        rm -f main

注意:gcc前面是tab键,而不是八个空格,如果用8个空格,输入make命令时,会报错:makefile:2: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.

测试

# 测试前,/functions目录下有4个文件:mytool1.h、mytool1.c、mytool2.h、mytool2.c。/目录下有文件:main.c。
[root@wu1 ~]# cd /
[root@wu1 /]# vim makefile
[root@wu1 /]# make
gcc -c main.c -I functions -o main.o
gcc -c functions/mytool1.c -o mytool1.o
gcc -c functions/mytool2.c -o mytool2.o
gcc main.o mytool1.o mytool2.o -o main
# 此时,/functions目录下的4个文件不变。/目录下有文件:main.c、makefile、main.o、mytool1.o、mytool2.o、main。
[root@wu1 /]# make clean
rm -f *.o
rm -f main
# 此时,/functions目录下的4个文件不变。/目录下有文件:main.c、makefile。

2、画出依赖关系图。

在这里插入图片描述

题目名称 linux实验-基本指令1 题目关键字 linux实验-基本指令1 题目录入时间 2013-4-1 22:36:02 题目内容 1、root帐号登录,查看/tmp目录,如果/tmp目录下没有子目录myshare,则建立该目录。 2、创建帐号testuser。 3、把myshare目录及其目录下的所有文件和子目录的拥有者该为testuser,工作组改为users。 4、切换至testuser帐号。进入/tmp/myshare目录,采用vim编辑器编写以上程序,程序名称为hello.sh: #!/bin/bash echo "app start" echo -e func (){ echo "hello world!" } func echo -e echo "app end" 5、保存hello.sh后,给予hello.sh拥有者可读、可写和可执行的权限,同组可读可执行,其他人可执行权限。 6、输入./hello.sh,观察程序输出的效果。 7、进入testuser的用户主目录,在这个目录下创建hello.sh的软链接,同时拷贝hello.sh到该目录下并改名为hello.sh.bak,要求拷贝时保留文件属性值。 8、退出testuser帐号,回到root帐号,从/开始查找后缀名为.conf的所有文件,把输出结果重定向到testuser帐号的主目录下的output.txt文件。 9、在上一步操作的.conf文件中找出文件容量最大的和最小那个,并把这两个文件的容量大小输出到output.txt文件中。 10、统计出系统中有多少个用户帐号,把数量输出到output.txt文件中。 11、把output.txt文件转换为windows记事本可正规打开的格式。 12、tar打包压缩testuser帐号主目录下的所有文件。 13、用U盘把上一步打包压缩文件拷贝到U盘上。 14、执行userdel -r testuser,执行rm -fr myshare 题目创建人 邝颖杰 题目注释 把打包压缩文件提交即可。
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值