WinDbg

WinDbg支持以下三种类型的命令:

·        常规命令,用来调试进程

·        点命令,用来控制调试器

·        扩展命令,可以添加叫WinDbg的自定义命令,一般由扩展dll提供这些命令

PDB文件

PDB文件是由链接器产生的程序数据库文件。私有PDB文件包含私有和公有符号,源代码行,类型,本地和全局变量信息。公有PDB文件不包含类型,本地变量和源代码行信息,且只包含共有成员的调试信息。

Dump文件

利用Dump工具,你可以获得进程的快照信息。一个mini-dump包含当前进程的所有线程,线程栈信息和已加载模块信息。一个full-dump包括更多信息,如堆信息。

使用WinDbg调试

1.       启动WinDbg

要用WinDbg(x86)调式32位程序,用WinDbg(x64)调试64位程序。

2.       使用帮助

任何时候都可以使用!help命令来获取帮助,查看命令的使用方法。

3.       设置SymbolFile Path,指定了符号库,我们才能看到详细的类型信息

SRV*c:\symbols*http://msdl.microsoft.com/download/symbols

WinDbg会将微软的符号库下载指定的本地目录中,以上设置可以使用以下命令来实现:

.symfixc:\symbols,此命令表示要连接到Microsoft服务器下载调试符号文件,符号文件将被下载到c:\symbols目录中。

还可以使用.sympath命令来显示当前的符号路径设置。

4.       重新加载符号

如果进入调试之后才指定的符号路径,需要使用命令来重新加载符号

.reload

5.       加载调试扩展

调试扩展定义了很多命令来调试.net程序。使用调式非托管代码的命令来调试.net程序是非常困难的。下面的命令加载了用于调试.net程序的sos模块。

a.      对于.Net Runtime 2.0

.loadby sos mscorwks

b.     对于.Net Runtime 4.0

.loadby sos clr

sos是一个dll,定义了很多针对.net assembly的调试命令,sos.dll针对不同的runtime有不同的版本。如果使用.load命令,需要为sos.dll指定完整路径。如果使用.loadby命令,则表示要在mscorwks.dll和clr.dll的同一目录下查找sos。对于.net程序,基本上都会加载mscorwks.dll(2.0)和clr.dll(4.0)。

6.       查看线程

a.      包括托管线程和非托管线程

~

b.     查看托管线程

!threads

c.      显示有关托管线程池的信息,包括队列中工作请求的数目、完成端口线程的数目和计时器的数目。

!ThreadPool

d.     切换线程(中间的数字表示线程号)

~0s

e.     查看线程栈, 仅提供托管代码的堆栈跟踪。

!clrstack [-a] [-l] [-p] [-n]

-p 选项显示托管函数的参数。

-l 选项将显示有关帧中的局部变量的信息。若SOSdebugging extension 未能检索本地名称,因此,本地名称的输出格式= 。

-a (all) 选项是一个表示 -l 和 -p 的组合的快捷方式。

-n 选项禁止显示源文件名和行号。

在基于x64 和IA-64 的平台上,SOS调试扩展不显示过渡帧。

f.       查看线程栈,只能正常显示非托管部分

k

g.      显示线程栈全部信息,包括托管和非托管部分

!dumpstack [-EE] [-n] [top stack [bottom stack]]

-EE 选项使DumpStack 命令仅显示托管函数。使用top 和bottom 参数可限制x86 平台上显示的堆栈帧。

-n 选项禁止显示源文件名和行号。如果调试器已指定选项

显示所有线程栈信息

h.     对一个进程中的所有线程运行 DumpStack 命令

!EEStack [-short] [-EE]

将-EE 选项直接传递给DumpStack 命令。-short 参数将输出限制为以下类型的线程:

·        已获取锁的线程。

·        己停止运行以允许垃圾回收的线程。

·        当前在托管代码中的线程。

i.     显示所有线程的堆栈

~*e !clrstack

j.       显示在当前堆栈的边界内找到的所有托管对象

!dumpstackobjects [-verify] [top stack [bottom stack]] 或 !dso

7.       查看堆中的所有对象信息,包括类型信息,个数,大小等

!dumpheap –stat

a.      指定对象类型,如果需要结果准确,需要使用全名称,类型名称是大小写敏感的

!dumpheap -type FlowThrottle –stat

b.     以上命令输出的第一列是mt(method table)信息,表示类型对象的地址。我们可以使用此信息来明确指定我们感兴趣的对象在堆中的信息。

!dumpheap -mt 000007feee769c00  -stat

注意,如果不指定-stat,那么输出每个对象的信息,使用-stat,将会看到统计信息。

c.      使用如下命令只输出对象地址

!dumpheap -mt 000007feee769c00  -short

d.     -short 选项将输出限制为只是每个对象的地址。这使您方便地以管道方式将输出从该命令转移到另一个调试器命令,以便自动化。

e.     -min 选项忽略小于 size 参数指定的大小(单位为字节)的对象。-max 选项忽略大于size 参数指定的大小(单位为字节)的对象。

8.       显示有关内部公共语言运行时数据结构所使用的进程内存的信息。

EEHeap [-gc][-loader]

-gc 和-loader 选项将此命令的输出限制为垃圾回收器或加载程序数据结构。有关垃圾回收器的信息列出了托管堆中每个段的范围。如果指针落在由-gc 给出的段范围内,则该指针是一个对象指针。

9.       打印对象信息,指定任何有效的对象地址,就能查看该对象的内容

!dumpobj

或者 !do

输出的对象信息中有每个属性的地址信息,所以可以继续使用!do命令来打印属性指向的对象信息。

!dumpobj –nofields

或者!do 

nofields选项指示不要输出对象字段信息,当对象是string类型时,该选项就非常有用。

10.   显示有关指定地址处的值类字段的信息。

DumpVC

MethodTable 参数使DumpVC 命令可以正确解释字段。值类不使用方法表作为它的第一个字段。

11.   输出多个对象信息

.foreach (myobj{!dumpheap -mt 008f4104-short}) {!do ${myobj}}

以上命令指示,对于堆中所有类型为008f4104的对象,依次调用!do命令。

12.   打印数组信息

!dumparray [-start] [-length ] [-details] [-nofields] 或者!da

·        -start 选项指定开始显示元素的起始索引。

·        -length 选项指定要显示的元素数量。

·        -details 选项使用 DumpObj 和 DumpVC 格式显示元素的详细信息。

·        -nofields 选项可阻止显示数组。此选项只有在指定了-detail 选项之后才可用。

下面的命令显示在地址 00ad28d0 处的数组内容。显示从第二个元素开始,连续显示五个元素。

!dumparray -start2 -length 5 -detail 00ad28d0

13.   输出app domain信息

!dumpdomain

枚举在指定的 AppDomain 对象地址内加载的每个Assembly 对象。若在调用DumpDomain 命令时不提供任何参数,则将列出进程中的所有AppDomain 对象。

14.   输出程序集信息

!dumpassembly

15.   打印方法表

!dumpmt [-MD]

显示有关指定地址处的方法表的信息。指定-MD 选项将显示与对象一起定义的所有方法的列表。每个托管对象都包含一个方法表指针。

16.   打印EEClass结构,其中可以看到类型静态变量信息

!dumpclass

显示有关与类型关联的 EEClass 结构的信息。DumpClass命令显示静态字段值,但不显示非静态字段值。使用DumpMT、DumpObj,Name2EE 或Token2EE 命令获取EEClass 结构的地址。

17.   显示异常

a.      使调试器在引发指定异常时停止,但在引发其他异常时继续运行。

!StopOnException [-derived] [-create | -create2]

-derived 选项用于捕获指定异常以及从指定异常派生的每个异常。

b.     显示当前活动线程上的最后一个异常

!PrintException [-nested] [-lines] [] 或 !PE

显示从指定地址处的Exception 类派生的任何对象的字段并设置这些字段的格式。如果不指定地址,PrintException命令将显示在当前线程上引发的最后一个异常。

-nested 选项显示有关嵌套异常对象的详细信息。

-lines 选项显示源信息(如果可用)。

c.      显示发生在所有线程上的最后的异常

~*e !pe

18.   调试GC相关信息

a.      显示有关对指定地址处的对象的引用(或根)的信息。

!GCRoot [-nostacks]

GCRoot 命令将检查整个托管堆和句柄表以查找其他对象内的句柄和堆栈上的句柄。然后,在每个堆栈中搜索对象的指针,同时还搜索终结器队列。此命令无法确定堆栈根是有效的还是已丢弃。使用CLRStack 和U 命令可对本地或参数值所属的帧进行反汇编,以便确定堆栈根是否仍在使用中。

-nostacks 选项将搜索限制为垃圾回收器句柄和 Freachable 对象。

b.     显示所有已进行终结注册的对象。

!FinalizeQueue [-detail] | [-allReady] [-short]

-detail 选项显示有关需要清理的任何 SyncBlocks 的额外信息以及有关等待清理的任何RuntimeCallableWrappers (RCW) 的额外信息。这两种数据结构都由终结器线程在运行时进行缓存和清理。

-allReady 选项显示所有准备终止的对象,无论它们已被垃圾回收标记成这样,还是将被下一个垃圾回收标记。在“准备终止”列表中的对象为不再为根的可终止对象。此选项可能耗费大量资源,因为它验证可终止队列中的所有对象是否仍然为根对象。

-short 选项将输出限制为每个对象的地址。如果与-allReady 一起使用,则将枚举具有不再为根的终结器的所有对象。如果单独使用,则将列出终结和“准备终结”队列中的所有对象。

19.  设置断点

!bpmdSystem.Windows.Forms.dllSystem.Windows.Forms.MessageBox.Show

第一个参数是dll文件名,第二个是完整的方法名。

20.  查看所有断点列表

bl

21.   释放当前断点, 让程序继续运行。让程序运行到断点后WinDBG会自动停下来。

g

22.   显示公共语言运行时版本。

!eeversion

23.   清除屏幕信息,该命令还你一个清洁的屏幕

.cls

24.   退出当前调试

q

//断点相关

bp + 地址设置断点

bl  显示已经设定的断点

bu + 地址设置断点,但是这种类型断点再下一次启动时被记录

bc 清除断点

对于断点范围,可以用*匹配,-表示一个范围,表达多个可用,号隔开

程序入口伪寄存器

WinDbg里有个伪寄存器叫$exentry,里面记录了程序的入口点。所以我们只要在命令输入栏里输入

bp $exentry

(bp就是用来下断点的命令,详细用法可以参考WinDbg的帮助文档)

//调试符号

ld kernerl32 //加载kernerl32模块的符号

lm   m k*        //显示已经加载的,以k开头的模块

ln         //显示最近操作过的模块名

dt dbg2     //检测模块

[[[[[[[[[[[[]]]]]]]]]]]]

x kernerl32!k* 显示模块kernerl32中所有以k开头的函数

dv 显示局部变量值

dv /i/t/v 显示局部变量的类型,值相关信息。

x !* / ? 显示指定模块的符号

x argc 查看变量argc的值。

dt argc 查看变量值

dt _PEB 7ffdd00 将内存地址7ffdd00开始的内容以PEB结构的方式显示出来。

dd 12000 L4 查看地址12000 后面的四个字

dds 12000 L100 查看堆栈上地址12000开始,后面的100个dword的内容,如果有调试符号,会将符号显示。此方法来追踪堆栈。(先看ebp,再用此方法)

dd ebp + 4, 返回地址, ebp + 8 第一个参数

[[[[[[[[[]]]]]]]]]

.kill 杀死调试进程

.restart 重新调试

[[[[[]]]]]]]]]]]]]]

k 显示调用堆栈

,kn加序号而已。

kb 显示前三个参数。第一个参数ebp+8;第二个ebp+0x0C;第三个ebp+0x10;dd ebp+0x14是第四个参数

kp 显示函数参数类型,数值

kp f f开关显示相邻栈基之差,从而可以推断出栈的健康状况。

[[[[[[[[[[]]]]]]]]]]

| 显示进程

~显示线程

~0 s 切换到 0号线程

[[[[[[[[[]]]]]]]]]

dv 显示函数参数&局部变量,注意,dv是跟栈帧相关的,对不同的栈帧显示不同的局部变量。

@1, kn 显示所有栈帧

@2, .frame选择想要查看的栈帧

@3, dv /i/v/t显示该栈帧里局部变量信息

@3, dv /i /V /t 显示变量基于栈帧的地址

如果没有私有符号,dv是不能显示变量信息的。

vc 生成的调试符号*.pdb windbg不认识,需要设置为c++/General/DebugInfo= C7 compatible

=====

sympath + c:\nasm 添加符号搜索路径

.sympath 显示符号搜索路径

//显示一定范围内存

!db L 32 : results in 32 bytes being displayed (as hexadecimal bytes),

//查看pe信息

!dh [Options] Address : 查看模块pe信息

!dh -f : display file headers

!dh -s : section headers

!dh -a : all header informations

查看结构体成员

dt nt!_EPROCESS

查看当前的irql

!irql

查看Verifier 检测统计信息

!verifier

查看某个内存地址属于那一个模块

!pool 地址

!lmi Address  : 查看模块的主要信息

!pcr 可以查看当前执行的线程及irql, 等信息

//

Why doesn't the WinDBG command !irql always return the correct IRQL for my target?

[Answer by Jake Oshins, jakeo_at_windows_dot_microsoft_dot_com. Workaround provided by James Antognini, antognini_at_mindspring_dot_nospam_dot_com, 27 August 2003]

!irql currently only produces useful results on a crashdump, not a live system. To retrieve the current IRQL on a live system you should instead use the !pcr command.

!processfield:列出EPROCESS的成员

该命令前的!号,意味着它来自于调试器的扩展模块―kdextx86.dll。该命令可显示内核用来代表一个进程的EPROCESS结构(该结构并没有正式的说明文档)的成员及其偏移量。

尽管该命令仅列出了成员的偏移量,但你也能很容易的猜出其正确的类型。例如,LockEvent位于0x70处,其下一个成员的偏移量为0x80。则该成员占用了16个字节,这与KEVENT结构非常类似。

!threadfields:列出ETHREAD成员

这是kdextx86.dll提供的另一个强大的选项。和!processfields类似,它列出未文档化的ETHREAD结构的成员及其偏移量。内核使用它表示一个线程.

//进程信息

!tep

!peb ,显示peb(进程信息)

//显示相关

dt ntdll!*teb* 列出匹配通配符的结构名

dt -v -r ntdll!_TEB

列出结构_TEB的成员信息

//显示变量地址

r $peb 显示模块peb的地址

//查看错误信息

!gle

//设置断点的技巧

可以直接把断点设在: kernel32!BaseProcessStart

1), 先用lm 显示所有已经加载的模块

2), dt our_exe_name!*main*  //在我们的程序模块中搜索包含main的地址(注意:如果未加载symbol是不能显示的!)

3), 如果存在,在our_exe_name!*main 处设置断点

=======

Command     SoftICE OllyDbg

Run         F5     F9

Step Into     F11 F7

Step Over     F10 F8

Set Break Point F8 F2

搜索内存

5、查找字符串

在步骤1我们运行程序时就记录了提示注册错误的字符串“Wrong Serial, try again!”,现在我们就要在内存找到该字符串的位置。

输入命令

s –a 00400000 L53000 “Wrong”

该命令的意思是以ASCII码形式在内存地址00400000往后53000个字节搜索字符串“Wrong”。

s,就是要调用查找的命令

-a,指定使用ASCII码的形式查找

00400000,指定要开始寻找的内存地址。

L53000,说明要在00400000往后的53000字节搜索。这个数值和00400000都可以从Stud_PE获得。00400000是程序的装入地址,而53000是映像的大小,也就是程序载入内存后占用的内存大小。使用这两个数值,基本上可以搜索到程序使用的整个内存范围。

“Wrong”,就不用多解释了,就是我们要寻找的字符串。不过WinDbg不支持模糊搜索,所以这里输入的字符串必定要完全正确。

内存访问断点

6、下内存访问断点

WinDbg中,ba命令代表Break On Access,即访问时中断。

我们在命令行输入:

ba r 1 0044108c

命令的意思是在内存0044108c的位置下字节的读断点。命令中各元素的含义可以参考帮助文档,这里不啰嗦。

输入bl,查看断点使用情况:

地址运算

? 0x33 + 0x44

运行后将得到计算和

3.查看和修改数据

调试中不可避免的要查看和修改数据

查看内存:

db/dw/dd/dq [Address]       字节/字/双字/四字方式查看数据

da/du [Address]           ASCII字符串/Unicode字符串方式查看指定地址

其它常用的如查看结构

dt nt!_EPROCESS

dt nt!_EPROCESS 89330da0 (把0x89330da0作为对象指针)

修改内存:

eb/ew/ed/eq/ef/ep Address [Values]

字节/字/双字/四字/浮点数/指针/

ea/eu/eza/ezu Address [Values]

ASCII字符串/Unicode字符串/以NULL结尾的ASCII字符串/以NULL结尾的Unicode字符串

搜索内存:

s -[b/w/d/q/a/u] Range Target

搜索字节/字/双字/四字/ASCII字符串/Unicode字符串

2.断点

断点之于调试当然是非常重要的

常用命令:

bp [Address]or[Symbol] 在指定地址下断

可以使用地址或符号,如

bp 80561259(Windbg默认使用16进制)

bp MyDriver!GetKernelPath

bp MyDriver!GetKernelPath+0x12

bp [Address] /p eprocess 仅当当前进程为eprocess时才中断

这个很常用,比如你bp nt!NtTerminateProcess,但是只想在某一进程触发此断点时才断下来,那就加上这个参数吧,因为内核中的代码是各个进程共用的,所以此命令很实用

bp [Address] /t ethread 仅当当前线程为ethread时才中断,用法跟/p参数类似

bu [Address]or[Symbol] 下一个未解析的断点(就是说这个断点需要延迟解析)

这个也很常用,比如我们的驱动名为MyDriver.sys,那么在驱动加载之前下断bu MyDriver!DriverEntry,

然后加载这个驱动时就可以断在驱动入口,并且这个是不需要调试符号支持的

bl 列出所有断点,L=List

bc[id] 清除断点,c=Clear,id是bl查看时的断点编号

bd[id] 禁用断点,d=Disable,id即断点编号

be[id] 启用断点,e=Enable,id为断点编号

windbg u只能显示几行怎么多显示 加 l 后面跟数字茹 u NtOpenProcess l100

u NtOpenKey  NtOpenkey+50   (显示50字节)  要查看的地址+要显示的字节

条件断点(condition breakpoint)的是指在上面3种基本断点停下来后,执行一些自定义的判断。

在基本断点命令后加上自定义调试命令,可以让调试器在断点触发停下来后,执行调试器命令。每个命令之间用分号分割。

语法格式如:

0:000> bpAddress"j (Condition) 'OptionalCommands'; 'gc' "

0:000> bpAddress".if (Condition) {OptionalCommands} .else {gc}"

这两条是等价的.

当然

.if

{

}

.else

{

}

更好理解.

0:000> bp `mysource.cpp:143` "j (poi(MyVar)>0n20) ''; 'gc' "

0:000> bp `mysource.cpp:143` ".if (poi(MyVar)>0n20) {} .else {gc}"  使用POI这里用的不是[] 而是()

若MyVar大于20则不stop,

否则stop下来进行调试.

MyVar符号表示符号所在的内存地址,而不是符号的数值,相当于C语言中的 &操作符的作用。Windbg命令poi的作用是取这个地址上的值,相当于C语言中的*操作符.因此这里取得MyVar的值.

伪寄存器,帮助保存调试的中间信息

考虑这样的情况,如果要记录某一个函数被执行了多少次,应该怎么做?简单的做法就是修改代码,在对应的函数入口做记录。可是,如果要记录的函数是系统API呢?

设置寄存器   条件断点

当eax内的值为0xa3时断点Sop. 没问题,Hah.

0:000> bp mydriver!myFunction "j @eax = 0xa3  '';'gc'"

0:000> bp mydriver!myFunction ".if @eax = 0xa3  {} .else {gc}"

但以下就不一定了,当eax中人值为0xc0004321时,

不一定会断下来.

为什么呢?

原因是内核态时,MASM会对EAX中的值进行符号扩展.

那么0xc0004321  会变成0xFFFFFFFFc0004321

这样当然断不下来啦。

0:000> bp mydriver!myFunction "j @eax = 0xc0004321  '';'gc'"

0:000> bp mydriver!myFunction ".if @eax = 0xc0004321  {} .else {gc}"

如何处理呢?看看下面就知道了.

0:000> bp mydriver!myFunction "j (@eax & 0x0`ffffffff) = 0x0`c0004321  '';'gc'"

0:000> bp mydriver!myFunction ".if (@eax & 0x0`ffffffff) = 0x0`c0004321  {} .else {gc}"

爽吧,高位清0!

下面的命令可以统计VirtualAllocEx被执行了多少次:

bp /1 /c @$csp @$ra;g

bp kernel32!VirtualAllocEx "r $t0=@$t0+1;.printf /"function executes: %d times /",@$t0;.echo;g"

这里用到的$t0就是Windbg提供的伪寄存器。可以用来存储中间信息。这里用它来存储函数执行的次数。r命令可以用来查看,修改寄存器(CPU寄存器和Windbg的伪寄存器都有效)的值。随便挑一个繁忙的进程,用这个命令设定断点后观察:

0:009> bp kernel32!VirtualAllocEx "r $t0=@$t0+1;.printf

/"function executes: %d times /",@$t0;.echo;g"

0:009> g

function executes: 1 times

function executes: 2 times

function executes: 3 times

function executes: 4 times

哈哈,这确实是一个好方法.

windbg 查看结构体_windbg常见命令相关推荐

  1. windbg 查看结构体_用WinDbg进行调试

    通往WinDbg的捷径(一) windbg的使用详细: http://wenku.baidu.com/view/f576c31e650e52ea55189832.html 导言 你钟情什么样的调试器? ...

  2. c语言结构体定义蚂蚁,C语言结构体(struct)常见使用方法

    C语言结构体(struct)常见使用方法 C语言结构体(struct)常见使用方法 基本定义:结构体,通俗讲就像是打包封装,把一些有共同特征(比如同属于某一类事物的属性,往往是某种业务相关属性的聚合) ...

  3. linux c 查看 结构体 宏 函数 关键字定义

    在linux c中搜索 结构体 宏定义 关键字 #查找结构体 grep -Rn --include="*.h" --include="*.c" 'struct ...

  4. xilinx sdk查看结构体定义open declaration

    先定义一个结构体,将光标放在XGpioPs上右键open declaration 查看具体定义 悬停有时也能显示

  5. linux查看内存条pn,实验:使用GDB查看结构体在内存中的存储方式

    结构体在内存中的表示形式是怎么样的? 结构体在内存中和普通变量存储没有太大的区别. 首先我们看看,计算机如何读取普通变量:   普通变量例如int是占据4个字节,计算机读内存的时候会从起始地址开始读, ...

  6. gdb 查看结构体地址内容_程序员的术与道:术——gdb基本操作

    1.gdb是什么 前面刚刚介绍了gcc,既然提到了gcc,下一个必须要提的是gdb.gdb同样是GNU出品的一款功能强大的工具,横扫linux世界. gdb是一款调试工具,其功能之强大,深入使用之后你 ...

  7. 图解windbg查看Win7结构体

    首先用windbg打开notepad.exe: dt命令显示局部变量.全局变量或数据类型的信息.它也可以仅显示数据类型.即结构和联合(union)的信息. 下面用dt命令查看Win7结构体: 查看pe ...

  8. Go 学习笔记(14)— 结构体定义、实例化、初始化、匿名结构体、结构体访问、结构体作为形参、结构体指针

    Go 语言中没有 "类" 的概念,也不支持 "类" 的继承等面向对象的概念.Go 语言不仅认为结构体能拥有方法,且每种自定义类型也可以拥有自己的方法. 1. 结 ...

  9. C/C++结构体四字节数据对齐

    为了避免混淆,做如下规定,以下代码若不加特殊说明都运行于32位平台,结构体的默认对齐值是8,各数据类型所占字节数分别为 char占一个字节 int占四个字节 double占八个字节. 两个例子 请问下 ...

  10. Go语言结构体(struct)

    Go 语言通过用自定义的方式形成新的类型,结构体是类型中带有成员的复合类型.Go 语言使用结构体和结构体成员来描述真实世界的实体和实体对应的各种属性. Go 语言中的类型可以被实例化,使用new或&a ...

最新文章

  1. geany配置python_Linux系统下搭建基于Geany+Python开发环境
  2. Python--编码的疑惑
  3. [转]MySQL查询表内重复记录
  4. centos7桌面登录root用户_CentOS7从一般用户切换到root用户
  5. django09: ORM以及CSRF(旧笔记)
  6. mysql函数match_Mysql全文搜索match…against的用法 | 学步园
  7. 手动创建两个文本文件text1.txt和text2.txt,按要求创建text3.txt
  8. MyBatis全局配置文件MyBatis-config.xml代码
  9. 网格搜索、随机搜索机器学习实战
  10. 基于Springboot+MYSQL实现在线点餐系统源码
  11. 无人机集群通信网络拓扑重构及关键技术研究∗
  12. 天翼网关 ddns设置_超高并发服务网关架构设计与实现
  13. oracle排列组合,Oracle SQL排列组合之排列问题
  14. Cesium开发:简单箭头画法
  15. 商城小程序通过交易组件实现直播带货
  16. 孕妇能吃哪些水果?三种水果帮你补充高营养
  17. 如何增加微信朋友圈分享链接的小图片
  18. springcloud微服务
  19. Android M Android6.0 权限管理 EasyPermission Demo
  20. Ansible批量管理Windows服务器,winrm配置

热门文章

  1. 或有事项会计处理研究 ——以广西上市公司为例
  2. 分析支付宝客户端的插件机制
  3. VMware.exe应用程序错误--应用程序无法正常启动(0xc000007b)错误解决方法
  4. Vue.js 踩坑记 (一)
  5. C++_深浅拷贝详解
  6. Zero-Shot Deep Domain Adaptation[reading notes]
  7. java jndi lookup_[导入]websphere下使用jndi lookup
  8. python to csv参数_pandas的to_csv()使用方法
  9. 启发函数 (Heuristic Function) —Octile
  10. 智商情商哪个重要_智商与情商哪个更重要 辩论