如何调试linux的网络驱动

如何调试linux的网络驱动,第1张

如何根据oops定位代码行

我们借用linux设备驱动第二篇:构造和运行模块里面的hello world程序来演示出错的情况,含有错误代码的hello world如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

#include <linux/inith>

#include <linux/moduleh>

MODULE_LICENSE("Dual BSD/GPL");

static int hello_init(void)

{

char p = NULL;

memcpy(p, "test", 4);

printk(KERN_ALERT "Hello, world\n");

return 0;

}

static void hello_exit(void)

{

printk(KERN_ALERT "Goodbye, cruel world\n");

}

module_init(hello_init);

module_exit(hello_exit);

  Makefile文件如下:

1

2

3

4

5

6

7

8

9

10

11

ifneq ($(KERNELRELEASE),)

obj-m := helloworldo

else

KERNELDIR = /lib/modules/$(shell uname -r)/build

PWD := $(shell pwd)

default:

$(MAKE) -C $(KERNELDIR) M=$(PWD) modules

endif

clean:

rm -rf o ~ core depend cmd ko modc tmp_versions modulesorder Modulesymvers

  很明显,以上代码的第8行是一个空指针错误。insmod后会出现下面的oops信息:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

[ 459516441] BUG: unable to handle kernel NULL pointer dereference at (null)

[ 459516445]

[ 459516448] PGD 0

[ 459516450] Oops: 0002 [#1] SMP

[ 459516452] Modules linked in: helloworld(OE+) vmw_vsock_vmci_transport vsock coretemp crct10dif_pclmul crc32_pclmul ghash_clmulni_intel aesni_intel vmw_balloon snd_ens1371 aes_x86_64 lrw snd_ac97_codec gf128mul glue_helper ablk_helper cryptd ac97_bus gameport snd_pcm serio_raw snd_seq_midi snd_seq_midi_event snd_rawmidi snd_seq snd_seq_device snd_timer vmwgfx btusb ttm snd drm_kms_helper drm soundcore shpchp vmw_vmci i2c_piix4 rfcomm bnep bluetooth 6lowpan_iphc parport_pc ppdev mac_hid lp parport hid_generic usbhid hid psmouse ahci libahci floppy e1000 vmw_pvscsi vmxnet3 mptspi mptscsih mptbase scsi_transport_spi pata_acpi [last unloaded: helloworld]

[ 459516476] CPU: 0 PID: 4531 Comm: insmod Tainted: G OE 3160-33-generic #44~14041-Ubuntu

[ 459516478] Hardware name: VMware, Inc VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 600 05/20/2014

[ 459516479] task: ffff88003821f010 ti: ffff880038fa0000 taskti: ffff880038fa0000

[ 459516480] RIP: 0010:[<ffffffffc061400d>] [<ffffffffc061400d>] hello_init+0xd/0x30 [helloworld]

[ 459516483] RSP: 0018:ffff880038fa3d40 EFLAGS: 00010246

[ 459516484] RAX: ffff88000c31d901 RBX: ffffffff81c1a020 RCX: 000000000004b29f

[ 459516485] RDX: 000000000004b29e RSI: 0000000000000017 RDI: ffffffffc0615024

[ 459516485] RBP: ffff880038fa3db8 R08: 0000000000015e80 R09: ffff88003d615e80

[ 459516486] R10: ffffea000030c740 R11: ffffffff81002138 R12: ffff88000c31d0c0

[ 459516487] R13: 0000000000000000 R14: ffffffffc0614000 R15: ffffffffc0616000

[ 459516488] FS: 00007f8a6fa86740(0000) GS:ffff88003d600000(0000) knlGS:0000000000000000

[ 459516489] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033

[ 459516490] CR2: 0000000000000000 CR3: 0000000038760000 CR4: 00000000003407f0

[ 459516522] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000

[ 459516524] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400

[ 459516524] Stack:

[ 459516537] ffff880038fa3db8 ffffffff81002144 0000000000000001 0000000000000001

[ 459516540] 0000000000000001 ffff880028ab5040 0000000000000001 ffff880038fa3da0

[ 459516541] ffffffff8119d0b2 ffffffffc0616018 00000000bd1141ac ffffffffc0616018

[ 459516543] Call Trace:

[ 459516548] [<ffffffff81002144>] do_one_initcall+0xd4/0x210

[ 459516550] [<ffffffff8119d0b2>] __vunmap+0xb2/0x100

[ 459516554] [<ffffffff810ed9b1>] load_module+0x13c1/0x1b80

[ 459516557] [<ffffffff810e9560>] store_uevent+0x40/0x40

[ 459516560] [<ffffffff810ee2e6>] SyS_finit_module+0x86/0xb0

[ 459516563] [<ffffffff8176be6d>] system_call_fastpath+0x1a/0x1f

[ 459516564] Code: <c7> 04 25 00 00 00 00 74 65 73 74 31 c0 48 89 e5 e8 a2 86 14 c1 31

[ 459516573] RIP [<ffffffffc061400d>] hello_init+0xd/0x30 [helloworld]

[ 459516575] RSP <ffff880038fa3d40>

[ 459516576] CR2: 0000000000000000

[ 459516578] ---[ end trace 7c52cc8624b7ea60 ]---

  

下面简单分析下oops信息的内容。

由BUG: unable to handle kernel NULL pointer dereference at (null)知道出错的原因是使用了空指针。标红的部分确定了具体出错的函数。Modules linked in: helloworld表明了引起oops问题的具体模块。call trace列出了函数的调用信息。这些信息中其中标红的部分是最有用的,我们可以根据其信息找到具体出错的代码行。下面就来说下,如何定位到具体出错的代码行。

第一步我们需要使用objdump把编译生成的bin文件反汇编,我们这里就是helloworldo,如下命令把反汇编信息保存到errtxt文件中:

1

objdump helloworldo -D > errtxt

  errtxt内容如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

helloworldo: file format elf64-x86-64

Disassembly of section text:

<span style="color:#ff0000;">0000000000000000 <init_module>:</span>

0: e8 00 00 00 00 callq 5 <init_module+0x5>

5: 55 push %rbp

6: 48 c7 c7 00 00 00 00 mov $0x0,%rdi

d: c7 04 25 00 00 00 00 movl $0x74736574,0x0

14: 74 65 73 74

18: 31 c0 xor %eax,%eax

1a: 48 89 e5 mov %rsp,%rbp

1d: e8 00 00 00 00 callq 22 <init_module+0x22>

22: 31 c0 xor %eax,%eax

24: 5d pop %rbp

25: c3 retq

26: 66 2e 0f 1f 84 00 00 nopw %cs:0x0(%rax,%rax,1)

2d: 00 00 00

0000000000000030 <cleanup_module>:

30: e8 00 00 00 00 callq 35 <cleanup_module+0x5>

35: 55 push %rbp

36: 48 c7 c7 00 00 00 00 mov $0x0,%rdi

3d: 31 c0 xor %eax,%eax

3f: 48 89 e5 mov %rsp,%rbp

42: e8 00 00 00 00 callq 47 <cleanup_module+0x17>

47: 5d pop %rbp

48: c3 retq

Disassembly of section rodatastr11:

0000000000000000 <rodatastr11>:

0: 01 31 add %esi,(%rcx)

2: 48 rexW

3: 65 gs

4: 6c insb (%dx),%es:(%rdi)

5: 6c insb (%dx),%es:(%rdi)

6: 6f outsl %ds:(%rsi),(%dx)

7: 2c 20 sub $0x20,%al

9: 77 6f ja 7a <cleanup_module+0x4a>

b: 72 6c jb 79 <cleanup_module+0x49>

d: 64 0a 00 or %fs:(%rax),%al

10: 01 31 add %esi,(%rcx)

12: 47 6f rexRXB outsl %ds:(%rsi),(%dx)

14: 6f outsl %ds:(%rsi),(%dx)

15: 64 fs

16: 62 (bad)

17: 79 65 jns 7e <cleanup_module+0x4e>

19: 2c 20 sub $0x20,%al

1b: 63 72 75 movslq 0x75(%rdx),%esi

1e: 65 gs

1f: 6c insb (%dx),%es:(%rdi)

20: 20 77 6f and %dh,0x6f(%rdi)

23: 72 6c jb 91 <cleanup_module+0x61>

25: 64 0a 00 or %fs:(%rax),%al

Disassembly of section modinfo:

0000000000000000 <__UNIQUE_ID_license0>:

0: 6c insb (%dx),%es:(%rdi)

1: 69 63 65 6e 73 65 3d imul $0x3d65736e,0x65(%rbx),%esp

8: 44 75 61 rexR jne 6c <cleanup_module+0x3c>

b: 6c insb (%dx),%es:(%rdi)

c: 20 42 53 and %al,0x53(%rdx)

f: 44 2f rexR (bad)

11: 47 50 rexRXB push %r8

13: 4c rexWR

Disassembly of section comment:

0000000000000000 <comment>:

0: 00 47 43 add %al,0x43(%rdi)

3: 43 3a 20 rexXB cmp (%r8),%spl

6: 28 55 62 sub %dl,0x62(%rbp)

9: 75 6e jne 79 <cleanup_module+0x49>

b: 74 75 je 82 <cleanup_module+0x52>

d: 20 34 2e and %dh,(%rsi,%rbp,1)

10: 38 2e cmp %ch,(%rsi)

12: 32 2d 31 39 75 62 xor 0x62753931(%rip),%ch # 62753949 <cleanup_module+0x62753919>

18: 75 6e jne 88 <cleanup_module+0x58>

1a: 74 75 je 91 <cleanup_module+0x61>

1c: 31 29 xor %ebp,(%rcx)

1e: 20 34 2e and %dh,(%rsi,%rbp,1)

21: 38 2e cmp %ch,(%rsi)

23: 32 00 xor (%rax),%al

Disassembly of section __mcount_loc:

0000000000000000 <__mcount_loc>:

  由oops信息我们知道出错的地方是hello_init的地址偏移0xd。而有dump信息知道,hello_init的地址即init_module的地址,因为hello_init即本模块的初始化入口,如果在其他函数中出错,dump信息中就会有相应符号的地址。由此我们得到出错的地址是0xd,下一步我们就可以使用addr2line来定位具体的代码行:

addr2line -C -f -e helloworldo d

此命令就可以得到行号了。以上就是通过oops信息来定位驱动崩溃的行号。

其他调试手段

以上就是通过oops信息来获取具体的导致崩溃的代码行,这种情况都是用在遇到比较严重的错误导致内核挂掉的情况下使用的,另外比较常用的调试手段就是使用printk来输出打印信息。printk的使用方法类似printf,只是要注意一下打印级别,详细介绍在linux设备驱动第二篇:构造和运行模块中已有描述,另外需要注意的是大量使用printk会严重拖慢系统,所以使用过程中也要注意。

以上两种调试手段是我工作中最常用的,还有一些其他的调试手段,例如使用/proc文件系统,使用trace等用户空间程序,使用gdb,kgdb等,这些调试手段一般不太容易使用或者不太方便使用,所以这里就不在介绍了。

第十三届全国青少年信息学奥林匹克联赛初赛试题

( 普及组 Pascal 语言 二小时完成)

● ● 全部试题答案均要求写在答卷纸上,写在试卷纸上一律无效 ●●

一、 单项选择题(共20题,每题15分,共计30分。每题有且仅有一个正确答案。)

1. 在以下各项中,( )不是CPU的组成部分。

A.控制器 B.运算器 C.寄存器 D.主板

2.在关系数据库中,存放在数据库中的数据的逻辑结构以( )为主。

A.二叉树 B.多叉树 C.哈希表 D.二维表

3.在下列各项中,只有( )不是计算机存储容量的常用单位。

A.Byte B.KB C.UB D.TB

4.ASCII码的含义是( )。

A.二→十进制转换码 B.美国信息交换标准代码

C.数字的二进制编码 D.计算机可处理字符的唯一编码

5.一个完整的计算机系统应包括( )。

A.系统硬件和系统软件 B.硬件系统和软件系统

C.主机和外部设备 D.主机、键盘、显示器和辅助存储器

6.IT的含义是( )。

A.通信技术 B.信息技术 C.网络技术 D.信息学

7.LAN的含义是( )。

A.因特网 B.局域网 C.广域网 D.城域网

8.冗余数据是指可以由其它数据导出的数据。例如,数据库中已存放了学生的数学、语文和英语的三科成绩,如果还存放三科成绩的总分,则总分就可以看作冗余数据。冗余数据往往会造成数据的不一致。例如,上面4个数据如果都是输入的,由于 *** 作错误使总分不等于三科成绩之和,就会产生矛盾。下面关于冗余数据的说法中,正确的是( )。

A.应该在数据库中消除一切冗余数据

B.用高级语言编写的数据处理系统,通常比用关系数据库编写的系统更容易消除冗余数据

C.为了提高查询效率,在数据库中可以保留一些冗余数据,但更新时要做相容性检验

D.做相容性检验会降低效率,可以不理睬数据库中的冗余数据

9.在下列各软件,不属于NOIP竞赛(复赛)推荐使用的语言环境有( )。

A.gcc B.g++ C.Turbo C D.Free Pascal

10.以下断电后仍能保存数据的有( )。

A.硬盘 B.高速缓存 C.显存 D.RAM

11.在下列关于计算机语言的说法中,正确的有( )。

A.高级语言比汇编语言更高级,是因为它的程序的运行效率更高

B.随着Pascal、C等高级语言的出现,机器语言和汇编语言已经退出了历史舞台

C.高级语言比汇编语言程序更容易从一种计算机上移植到另一种计算机上

D.C是一种面向对象的高级计算机语言

12.近20年来,许多计算机专家都大力推崇递归算法,认为它是解决较复杂问题的强有力的工具。在下列关于递归算法的说法中,正确的是( )。

A.在1977年前后形成标准的计算机高级语言“FORTRAN77”禁止在程序使用递归,原因之一是该方法可能会占用更多的内存空间

B.和非递归算法相比,解决同一个问题,递归算法一般运行得更快一些

C.对于较复杂的问题,用递归方式编程一般比非递归方式更难一些

D.对于已经定义好的标准数学函数 sin(x),应用程序中的语句“y=sin(sin(x));”就是一种递归调用

13.一个无法靠自身的控制终止的循环成为“死循环”,例如,在C语言程序中,语句“while(1) printf(“”);”就是一个死循环,运行时它将无休止地打印号。下面关于死循环的说法中,只有( )是正确的。

A.不存在一种算法,对任何一个程序及相应的输入数据,都可以判断是否会出现死循环,因而,任何编译系统都不做死循环检查

B.有些编译系统可以检测出死循环

C.死循环属于语法错误,既然编译系统能检查各种语法错误,当然也应该能检查出死循环

D.死循环与多进程中出现的“死锁”差不多,而死锁是可以检测的,因而,死循环也可以检测的

14.在Pascal语言中,表达式 (23 or 2 xor 5)的值是( )。

A.18 B.1 C.23 D.32

15.在Pascal语言中,判断整数a等于0或b等于0或c等于0的正确的条件表达式是( )。

A.not ((a<>0) or (b<>0) or (c<>0))

B.not ((a<>0) and (b<>0) and (c<>0))

C.not ((a=0) and (b=0)) or (c<>0)

D.(a=0) and (b=0) and (c=0)

16.地面上有标号为A、B、C的三根柱,在A柱上放有10个直径相同中间有孔的圆盘,从上到下依次编号为1,2,3……,将A柱上的部分盘子经过B柱移入C柱,也可以在B柱上暂存。如果B柱上的 *** 作记录为“进、进、出、进、进、出、出、进、进、出、进、出、出”。那么,在C柱上,从下到上的编号为( )。

A.2 4 3 6 5 7 B.2 4 1 2 5 7 C.2 4 3 1 7 6 D.2 4 3 6 7 5

17.与十进制数1770对应的八进制数是( )。

A.3350 B.3351 C.3352 D.3540

18.设A=B=True,C=D=False,一下逻辑运算表达式值为假的有( )。

A.(「A∧B)∨(C∧D∨A) B.「(((A∧B)∨C)∧D)

C.A∧(B∨C∨D)∨D D.(A∧(D∨C))∧B

19.(2070)16 + (34)8 的结果是( )。

A.(8332)10 B.(208A)16 C.(100000000110)2 D.(20212)8

20.已知7个节点的二叉树的先根遍历是1 2 4 5 6 3 7(数字为节点的编号,以下同),中根遍历是4 2 6 5 1 7 3,则该二叉树的后根遍历是( )。

A.4 6 5 2 7 3 1 B.4 6 5 2 1 3 7 C.4 2 3 1 5 4 7 D.4 6 5 3 1 7 2

二、问题求解(共2题,每题5分,共计10分)。

1、(子集划分)将n个数(1,2,…,n)划分成r个子集。每个数都恰好属于一个子集,任何两个不同的子集没有共同的数,也没有空集。将不同划分方法的总数记为S(n,r)。例如,S(4,2)=7,这7种不同的划分方法依次为{(1),(234)},{(2),(134)},{(3),(124)},{(4),(123)},{(12),(34)},{(13),(24)},{(14),(23)}。当n=6,r=3时,S(6,3)=______________。

(提示:先固定一个数,对于其余的5个数考虑S(5,3)与S(5,2),再分这两种情况对原固定的数进行分析。)

2、(最短路线)某城市的街道是一个很规整的矩形网络(见下图),有7条南北向的纵街,5条东西向的横街。现要从西南角的A走到东北角的B,最短的走法共有多少种?___________

(图画不了)

三、阅读程序写结果(共4题,每题8分,共计32分。)

1、program j301;

var i,a,b,c,x,y:integer;

p:array[04] of integer;

begin

y:=20;

for i:=0 to 4 do read(p);

readln;

a:=(p[0]+p[1])+(p[2]+p[3]+p[4]) div 7;

b:=p[0]+p[1] div ((p[2]+p[3]) div p[4]);

c:=p[0]p[1] div p[2];

x:=a+b-p[(p[3]+3) mod 4];

if (x>10)

then y:=y+(b100-a) div (p[p[4] mod 3]5)

else

y:=y+20+(b100-c) div (p[p[4] mod 3]5);

writeln(x,',',y);

end

{注:本例中,给定的输入数据可以避免分母为0或数组元素下表越界。}

输入:6 6 5 5 3 输出:______________________

2、program j302;

var a,b:integer;

var x,y:^integer;

procedure fun(a,b:integer);

var k:integer;

begin k:=a; a:=b; b:=k; end;

begin

a:=3; b:=6;

x:=@a; y:=@b;

fun(x^,y^);

writeln(a,',',b);

end

输出:_______________________________

3、program j303;

var a1:array[150] of integer;

var i,j,t,t2,n,n2:integer;

begin

n:=50;

for i:=1 to n do a1:=0;

n2:=round(sqrt(n));

for i:=2 to n2 do

if (a1=0) then

begin

t2:=n div i;

for j:=2 to t2 do a1[ij]:=1;

end;

t:=0;

for i:=2 to n do

if (a1=0) then

begin

write(i:4); inc(t);

if (t mod 10=0) then writeln;

end;

writeln;

end

输出:_____________________________________________

_____________________________________________

4、Program j304;

Type str1=string[100];

Str2=string[200];

Var

S1:str1; s2:str2;

Function isalpha(c:char):Boolean;

Var i:integer;

Begin

i:=ord(c);

if ((i>=65) and (i<=90)) or ((i>=97) and (i<=122)) then

isalpha:=true

else isalpha:=false;

end;

function isdigit(c:char):Boolean;

var i:integer;

begin

i:=ord(c); if (i>=48) and (i<=57) then isdigit:=true

else isdigit:=false;

end;

procedure expand(s1:str1;var s2:str2);

var i,j:integer; a,b,c:char;

begin

j:=1; c:=char(1); i:=0;

while (i<=ord(s1[0])) do

begin inc(i); c:=s1;

if c='-' then begin {1}

a:=s1[i-1]; b:=s1[i+1];

if (isalpha(a) and isalpha(b)) or (isdigit(a) and isdigit(b)) then begin

dec(j);

while (ord(upcase(a))<ord(upcase(s1[i+1]))) do

begin

s2[j]:=a; inc(j); inc(a); end;

end

else

begin s2[j]:=c; inc(j); end;

end{1}

else begin s2[j]:=c; inc(j); end; end; s2[0]:=char(j-2); end;

begin readln(s1); expand(s1,s2); writeln(s2);

end

输入:wer2345d-h454-82qqq 输出:__________________________

四、完善程序(前4空,每空25分,后6空,每空3分,共28分)。

1、(求字符的逆序)下面的程序的功能是输入若干行字符串,每输入一行,就按逆序输出该行,最后键入-1终止程序。

请将程序补充完整。

Program j401;

type str1=string[100];

var line:str1; kz:integer;

procedure reverse(var s:str1);

var I,j:integer; t:char;

begin

i:=1; j:=length(s);

while (i<j) do begin

t:=s; s:=s[j]; s[j]:=t;

; ;

end;

end;

begin

writeln(‘continue -1 for end’);

readln(kz);

while ( )do

begin

readln(line);

;

writeln(line);

writeln(‘continue -1 for end’);

readln(kz);

end;

end

2 2 3 3

2 -1 1 3

4 1 1 5

4 4 5 5

2、(棋盘覆盖问题)在一个2k×2 k个方格组成的棋盘中恰有一个方格与其它方格不同(图中标记为-1的方格),称之为特殊方格。现用L型(占3个小方格)纸片覆盖棋盘上除特殊方格的所有部分,各纸片不得重叠,于是,用到的纸片数恰好是(4 k-1)/3。在下表给出的一个覆盖方案中,k=2,相同的3各数字构成一个纸片。

下面给出的程序使用分治法设计的,将棋盘一分为四,依次处理左上角、右上角、左下角、右下角,递归进行。请将程序补充完整。

(图画不了郁闷)

Program j402;

type arr1=array[165] of integer;

arr2=array[165] of arr1;

var board:arr2; tile:integer; size,dr,dc:integer;

procedure chessboard(tr,tc:integer; dr,dc:integer; var size:integer);

var t,s:integer;

begin

if (size=1) then ;

t:=tile; inc(tile);

s:=size div 2;

if then chessboard(tr,tc,dr,dc,s) else begin

board[tr+s-1]:=t;

end;

if (dr<tr+s) and (dc>=tc+s) then chessboard(tr,tc+s,dr,dc,s)

else begin board[tr+s-1][tc+s]:=t;

; end;

if (dr>=tr+s) and (dc<tc+s) then chessboard(tr+s,tc+s,dr,dc,s) else begin

board[tr+s][tc+s]:=t;

; end;

if (dr>=tr+s) and (dc>=tc+s) then chessboard(tr+s,tc+s,dr,dc,s)

else begin board[tr+s][tc+s]:=t;

; end;

end;

procedure prt1(n:integer);

var I,j:integer;

begin

for I:=1 to n do begin

for j:=1 to n do write(board[j]:3);

writeln;

end;

end;

begin

writeln(‘input size(4/8/16/64):’);

readln(size); writeln(‘input the position of special block(x,y):’);

readln(dr,dc); board[dr][dc]:=-1;

tile:=1; chessboard(1,1,dr,dc,size); prt1(size);

end

NOIP2007年普及组(Pascal语言)参考答案与评分标准

一、单项选择题:(每题15分)

题号 1 2 3 4 5 6 7 8 9 10

答案 D D C B B B B C C A

题号 11 12 13 14 15 16 17 18 19 20

答案 C A A A B D C D A A

二、问题求解:(每题 5分)

1.90 2.210

三、阅读程序写结果

1 15, 46(对1个数给4分,无逗号扣1分)

2 3, 6

3 2 3 5 7 11 13 17 19 23 29

31 37 41 43 47

4 wer2345defgh45456782qqq

四、完善程序(前4空(①--④),每空25分,后6空(⑤--⑩),每空3分)

1.

① inc(i) 或i:=i+1

② dec(j) 或 j:=j-1

③ kz<>-1

④ reverse(line)

2

⑤ exit

⑥ (dr<tr+s)and(dc<tc+s)

⑦ chessboard(tr,tc,tr+s-1,tc+s-1,s)

⑧ chessboard(tr,tc+s,tr+s-1,tc+s,s)

⑨ chessboard(tr+s,tc,tr+s,tc+s-1,s)

⑩ chessboard(tr+s,tc+s,tr+s,tc+s,s)

貌似我考过了 不难

希望对你能有所帮助。

  积分计算公式如下:

  1含有a+bx的积分公式

  2含有√(a+bx)的积分公式

  3含有x^2±α^2的积分

  4

  含有ax^2+b(a>0)的积分

  5含有√(a^2+x^2) (a>0)的积分

  6含有ax^2+b(a>0)的积分

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/12163584.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-21
下一篇 2023-05-21

发表评论

登录后才能评论

评论列表(0条)

保存