如何手工抓取dump文件及分析

在生产环境下进行故障诊断时,为了不终止正在运行的服务或应用程序,有两种方式可以对正在运行的服务或应用程序的进程进行分析和调试。

首先一种比较直观简洁的方式就是用WinDbg等调试器直接attach到需要调试的进程,调试完毕之后再detach即可。但是这种方式有个缺点就是执行debugger命令时必须先break这个进程,执行完debug命令之后又得赶紧F5让他继续运行,因为被你break住的时候意味着整个进程也已经被你挂起。另外也经常会由于First Chance Excetpion而自动break,你得时刻留意避免长时间break整个进程。所以这样的调试方式对时间是个很大的考验,往往没有充裕的时间来做仔细分析。

另一种方式则是在出现问题的时候,比如CPU持续长时间100%,内存突然暴涨等非正常情况下,通过对服务进程snapshot抓取一个dump文件,完成dump之后先deatch,让进程继续运行。然后用windbg等工具来分析这个抓取到的dump文件。

那么如何在不终止进程的情况下抓取dump文件呢?Debugging Tools for Windows里提供了一个非常好的工具,adplus.vbs。从名字可以看出,实际上是一个vb脚本,只是对cdb调试器作的一个包装脚本。

其路径与Debugging Tools for Windows的安装路径相同,使用的方法也很简单,如下所示:

adplus.vbs -hang -p 1234 -o d:\dump

其中-hang指明使用hang模式,亦即在进程运行过程中附加上去snapshot抓取一个dump文件,完成之后detach。与之对应的是-crash崩溃模式,用户先启动adplus,然后由它启动要监控的程序,在出现异常崩溃时自动生成dump文件,或者通过Ctrl-C人为发出抓取指令。但是-crash模式在抓取完成之后,被监控的进程就必须终止。因此我们在这里只选用-hang模式。

-p是要调试的进程ID,比如ASP.NET应用线程池,在Win2003下就是w3wp.exe

-o 指定要output的dump文件路径。

另外,与adplus类似的,有个UserDump工具,但是抓取用户模式的进程,而adplus则是内核模式和用户模式两者皆可。

而总所周至的Dr. Waston,则会在进程崩溃之后的自动时候抓取dump文件,一样可以用于windbg等调试器来事后分析程序崩溃时的状态。

====================
0:000> !dumpheap -stat 
No export dumpheap found 
======解决方法:
.load clr20\sos.dll,你要先执行的。sos.dll在默认的c:\windows\microsoft.net\framework\v2.....下面,你复制到c:\program files\debugging tools for windows下面的clr20目录下面(clr20是你手工创建的) 
 =======================
     
  在.NET下开发时,最基本的调试方法就是使用Visual Studio的单步调试。但是对于一些特殊情况,特别是涉及到CLR内部的时候使用这种方式就达不到目的了。 
  如果要查看运行时内存使用情况,IL代码,CLR信息等可以使用以下两种方式: 
  1、使用VS2005 + sos.dll 
  2、使用Windbg + sos.dll 
  第二种方式功能更加强大,下面我就通过实际操作展示一下怎么使用这种方法得到运行时ArrayList内部的值。 
  有人可能会说:我直接用Visual Studio的单步调试岂不是更快?当然,这个只是一个演示,通过这个演示是为以后的高级调试打下基础 
   
  在操作之前,先熟悉一下基本知识: 
  A、使用VS2005 + sos.dll调试 
  1、需要在项目->属性->调试-〉启用非托管代码调试 
  2、打开调试-〉窗口-〉即时 
  3、在即时窗口中输入 !load sos 加载调试模块 
  4、输入其它调试语句 
   
  B、使用Windbg + sos.dll 
  1、去微软的网站下载最新的Windbg 
  2、打开Windbg在File-〉Symbol File Path ...窗口中输入 srv*c:\symbols*http://msdl.microsoft.com/download/symbols 
  3、运行需要调试的程序,然后在Windbg中File-〉Attach to Process中选择刚才运行的程序 
  4、在出现的Command窗口中就可以输入调试语句 
  5、常用调试语句: 
   lm //查看加载了哪些模块 
   .load C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\sos.dll //加载调试模块 
   ld TestClass //加载调试符号 
   !name2ee TestClass.exe TestClass.Program.test //显示test方法相关的地址 
   !dumpmt -md 00976d48 //得到类的成员函数详细信息 
   !dumpil 00973028 // 显示这个方法被编译器编译之后的IL代码 
   !dumpheap -stat //该命令显示程序中所有对象的统计信息,显示的大小是对象本身的大小,不包括对象里面值的大小 
   !dumpheap -mt 790fcb30 //该命令显示MethodTable 790fcb30的详细信息 
   !gcroot 012919b8 //来显示一个实例的所属关系 
   !dumpobj(do) 012a3904 //显示一个对象的具体内容,看对象里面有什么,值是什么 
   !ObjSize 012a1ba4 //对象实际在内存中的大小 
   !eeheap -gc //查看托管堆的情况(包括大小) 
   !DumpArray //查看数组信息 
   下面就来看看具体的调试步骤: 
  1、我们的测试代码 
   
   
  namespace TestClass 
  { 
   class Program 
   { 
   [STAThread] 
   static void Main(string[] args) 
   { 
   ArrayList list = new ArrayList(); 
   list.Add("aaaa"); 
   list.Add("bbbb"); 
   Console.ReadLine(); 
   } 
   } 
  }很简单,就是一个ArrayList 
   
  运行这个程序(开始执行,不调试),然后进入Windbg,Attach到这个进程 
   
  2、查看所有堆栈信息 
  0:004> !dumpheap -stat 
   MT Count TotalSize Class Name 
  7910062c 1 12 System.Security.Permissions.SecurityPermission 
  7918e284 1 16 System.IO.TextReader+SyncTextReader 
  79102d10 1 20 Microsoft.Win32.SafeHandles.SafeFileMappingHandle 
  79102cb4 1 20 Microsoft.Win32.SafeHandles.SafeViewOfFileHandle 
  79101d30 1 20 System.Text.InternalEncoderBestFitFallback 
  79100a7c 1 20 Microsoft.Win32.SafeHandles.SafeFileHandle 
  79105cd4 1 24 System.Collections.ArrayList 
  ...... 
  7912ad90 11 9036 System.Object[] 
  790fcb30 2083 131492 System.String 
  Total 2202 objects 
  除了我们的ArrayList外,还有很多其它的系统信息,先不用管它 
   
  3、查看我们的ArrayList的信息 
  0:004> !dumpheap -mt 79105cd4 
   Address MT Size 
  012a1b88 79105cd4 24 
  total 1 objects 
  Statistics: 
   MT Count TotalSize Class Name 
  79105cd4 1 24 System.Collections.ArrayList 
  Total 1 objects 
   
  4、查看对应地址内部实际的值 
  0:004> !do 012a1b88 
  Name: System.Collections.ArrayList 
  MethodTable: 79105cd4 
  EEClass: 79105c28 
  Size: 24(0x18) bytes 
   (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll) 
  Fields: 
   MT Field Offset Type VT Attr Value Name 
  7912ad90 40008df 4 System.Object[] 0 instance 012a1bb0 _items 
  791018e0 40008e0 c System.Int32 1 instance 2 _size 
  791018e0 40008e1 10 System.Int32 1 instance 2 _version 
  790fc35c 40008e2 8 System.Object 0 instance 00000000 _syncRoot 
  7912ad90 40008e3 1c0 System.Object[] 0 shared static emptyArray 
   >> Domain:Value 00149c58:012a1ba0 << 
  可以看到ArrayList的大小为2,具体的值保存在地址012a1bb0中,是一个System.Object[]类型的数组 
   
  5、查看数组信息 
  0:004> !DumpArray 012a1bb0 
  Name: System.Object[] 
  MethodTable: 7912ad90 
  EEClass: 7912b304 
  Size: 32(0x20) bytes 
  Array: Rank 1, Number of elements 4, Type CLASS 
  Element Methodtable: 790fc35c 
  [0] 012a1b50 
  [1] 012a1b6c 
  [2] null 
  [3] null 
   
  6、查看数组内对象的值 
  0:004> !do 012a1b50 
  Name: System.String 
  MethodTable: 790fcb30 
  EEClass: 790fca90 
  Size: 26(0x1a) bytes 
   (C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll) 
  String: aaaa 
  Fields: 
   MT Field Offset Type VT Attr Value Name 
  791018e0 4000096 4 System.Int32 1 instance 5 m_arrayLength 
  791018e0 4000097 8 System.Int32 1 instance 4 m_stringLength 
  790fe534 4000098 c System.Char 1 instance 61 m_firstChar 
  790fcb30 4000099 10 System.String 0 shared static Empty 
   >> Domain:Value 00149c58:790d81bc << 
  7912b1d8 400009a 14 System.Char[] 0 shared static WhitespaceChars 
   >> Domain:Value 00149c58:012a16f0 <<  
====================

windbg使用小总结
【抓dump】
1、一般抓法
adplus -hang -p 3230 -quiet 抓3230 pid进程,hang模式,相当于把那个进程暂停住,取内存快照
adplus -crash -pn w3wp -quiet 抓w3wp进程,crash模式,当那个进程崩溃结束的时候自动抓取当时的内存
adplus -hang -iis -quiet 抓IIS相关进程,包括其上host的web应用,以及iis自身
2、抓window服务
http://support.microsoft.com/kb/824344/zh-cn
3、远程抓
http://blog.joycode.com/tingwang/archive/2006/08/11/79763.aspx
4、抓蓝屏和死机的dump
电脑无故重启或者蓝屏会在C:\WINDOWS\Minidump\下保存一个minidump,但是这个minidump可用的命令很少,一般只打!analyze –v看到是哪个进程引起的,还有相关的驱动模块就基本定位问题了。
5、IIS回收的时候抓
http://blog.yesky.com/blog/omakey/archive/2006/12/17/1618015.html
6、计划任务抓
比如一个进程起来后不知道它什么时候会意外崩溃,可以在计划任务里用crash里抓,当那个进程意外终止的时候,cdb可以直接附加上去,抓取当时的dump,如果要抓一些会自动重启的进程,而且要抓每次重启前的dump,可以参考附录里一节。

【常用命令】
1、先path C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727,把.net路径设置为path环境变量,一遍在windbg里可以直接.load sos,而不必.load C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\sos.dll
2、ld demo,加载你程序的pdb文件,调试.net程序一般要把kernel32和mscorwks的符号加载上,关于这两个东西大家可以查资料,尤其是后者有哪些函数可以多了解一些。
3、在windbg的file/symbol file path对话框里输入以下文字,以便自动加载和下载符号
C:\WINDOWS\Symbols;d:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\symbols;.sympath SRV*d:\localsymbols*http://msdl.microsoft.com/download/symbols
其中有windows、.net2.0和自动从网上下载的调试符号,注意根据自己的情况适当修改目录

【调试死锁】
1、!syncblk,查看哪些线程拿到了锁
2、~67e!clrstack 跳到某个拿到锁的线程看它正在干什么操作,迟迟不肯释放锁
3、!runaway 查看这个占有锁的线程运行了多长时间。
4、~*e!clrstack查看所有线程的托管堆栈,看看哪些是正在等待锁的,比如hang在System.Threading.Monitor.Enter(System.Object) 
5、~136s选择该线程,显示如下
0:000> ~136s eax=00005763 ebx=08deeb5c ecx=03eff0d4 edx=5570ab69 esi=08deeb5c edi=7ffd6000 eip=7c95ed54 esp=08deeb10 ebp=08deebb8 iopl=0 nv up ei pl zr na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246 ntdll!KiFastSystemCallRet: 7c95ed54 c3 ret
找到ecx寄存器的值,复制后ctrl+f,向上查找,会找到!syncblk的地方,如下
0:000> !syncblk Index SyncBlock MonitorHeld Recursion Owning Thread Info SyncBlock Owner 1906 03ee4be4 5 1 03ee8f88 22c8 67 185e2ef0 System.Object 5390 052ca39c 3 1 05292b30 1dd4 49 1060d3ac System.Object 9372 0530702c 15 1 0012d3a8 1aa8 80 185e7704 System.Object 11428 03eff0d4 35 1 053b8fa8 169c 120 166acd98 System.Object 15278 0531c6b4 61 1 06bc1430 26d8 86 1a5bea88 System.Object
可以看到136线程等待的锁被120号线程占着不放(格式有点乱,凑合看),
6、有时候通过ecx寄存器找锁不是很确定,可以用~* kb来把所有线程堆栈打出来,然后根据!syncblk出来的同步快的值去搜索大概有多少个线程在等那个锁。因为同样是等待锁,可等的状态不一样,有的在Q里,有的锁已经升级,有的去尝试去拿锁了,所以不一定当时ecx寄存器指向那块内存,具体如何找到某个正在等待锁的线程等待的锁的内存地址,以及它正等待的这个锁被哪个线程拿着,我还没琢磨出规律来,但一般情况下,如果有其它同步对象的话,更难查。.net里用我上面说的几步就能查出锁的问题了。


【内存泄漏】
1、!dumpheap -stat看看哪些对象个数最多,占内存最大,
2、找到某个格式比较多的对象,可以看它的方法表,然后用!dumpheap -mt 66398fa4去随机找几个对象的地址
3、用!do 1e5a22bc命令去查看几个对象的状态,属性的值等,看看正常不正常
4、用!gcroot -nostacks 1e5a22bc去查看几个对象的根正常不正常,如果有些对象的根不是自己预先设计的那样,很可能被自己没想到的对象强引用了,所以GC无法回收它,就泄漏了。
【CPU百分百】
主要用几个计数器和!runaway命令,具体见以下链接
http://www.cnblogs.com/onlytianc ... 7/06/03/769307.html
【线程池耗尽】
!threadpool 能看到完成端口,线程池工作线程和timer回调各占线程池的情况。
【其它】
1、!eestack -short -ee查看所有重要(获取锁的,托管的,停止并允许回收的)线程的dumpstack,差不多相当于~*e!dumpstack
2、.time 可以看到进程跑了多少时间
3、!dso 查看当前线程里有哪些对象,分析内存泄漏问题也许会用到
【小结】
要想很好的用windbg排查.net问题,首先要了解一些clr宿主的基础知识,以及IL的一些基础,还有简单的寄存器和汇编尝试,再就是有个好的思路,最后就是经验和对代码逻辑的理解。


【附录:写了一个自动抓dump的工具,可在程序异常退出的时候抓dump】
【使用方法】
1、先在cmd下运行以下命令确保计划任务开着
net start "task scheduler"
2、执行以下命令安排自动抓包
at 13:27 d:\myapp\autodump\processmon.exe
其中计划启动的时间和自动抓包的程序路径要根据情况设置,计划启动之前当前用户一定要注销。
【相关配置】
<appSettings>
  <add key="adplusPath" value="D:\MyApp\Debugging\adplus.vbs"/><!--adplus的路径-->
  <add key="ProcessName" value="w3wp"/><!--要抓dump的进程的名字,可用部分名字,不用完整的-->
</appSettings>


【源码】


[csharp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Diagnostics;  
  4. using System.Threading;  
  5.   
  6. namespace ProcessMon  
  7. {  
  8.     class Program  
  9.     {  
  10.         static readonly List<int> _dumpPIDs = new List<int>();  
  11.         private static readonly string _processName = System.Configuration.ConfigurationManager.AppSettings["ProcessName"];  
  12.         private static readonly string _adplusPath = System.Configuration.ConfigurationManager.AppSettings["adplusPath"];  
  13.         static void Main(string[] args)  
  14.         {  
  15.             while(true)  
  16.             {  
  17.                 Console.WriteLine("..");  
  18.                 ThreadProc();  
  19.                 Thread.Sleep(10000);  
  20.             }  
  21.         }  
  22.   
  23.         private static void ThreadProc()  
  24.         {  
  25.             foreach(Process vProcess in Process.GetProcesses())  
  26.             {  
  27.                 try  
  28.                 {                
  29.                     string  processName  =  vProcess.ProcessName.ToLower();  
  30.                     if (processName.IndexOf(_processName) >= 0)  
  31.                     {  
  32.                         Console.WriteLine("{0}-{1}", vProcess.ProcessName, vProcess.Id);  
  33.   
  34.                         if (_dumpPIDs.Contains(vProcess.Id))  
  35.                             continue;  
  36.                         _dumpPIDs.Add(vProcess.Id);  
  37.         
  38.                         DumpProcessDeg d = DumpProcess;  
  39.                         d.BeginInvoke(vProcess.Id, nullnull);  
  40.                         DumpProcess(vProcess.Id);  
  41.                     }  
  42.                 }  
  43.                 catch(Exception ex)  
  44.                 {  
  45.                     Console.WriteLine(ex);  
  46.                 }  
  47.             }  
  48.         }  
  49.   
  50.         private delegate void DumpProcessDeg(int pid);  
  51.         static  void  DumpProcess(int pid)  
  52.         {  
  53.             ProcessStartInfo  Info  =  new  System.Diagnostics.ProcessStartInfo();  
  54.             Info.FileName = _adplusPath;  
  55.             Info.Arguments = string.Format("-crash -p {0} -quiet",pid);  
  56.             Info.WorkingDirectory  =  "C:\\";  
  57.             Process  Proc  ;  
  58.             try  
  59.             {  
  60.                 Proc  =  Process.Start(Info);  
  61.             }  
  62.             catch(System.ComponentModel.Win32Exception  e)  
  63.             {  
  64.                 Console.WriteLine("系统找不到指定的程序文件。\r{0}",  e);  
  65.                 return;  
  66.             }  
  67.             Proc.EnableRaisingEvents = true;  
  68.             Console.WriteLine("外部程序的开始执行时间:{0}",  Proc.StartTime);  
  69.             Proc.WaitForExit(60000);  
  70.             if(Proc.HasExited  ==  false){  
  71.                 Console.WriteLine("由主程序强行终止外部程序的运行!");  
  72.                 Proc.Kill();  
  73.             }  
  74.             else{  
  75.                 Console.WriteLine("由外部程序正常退出!");  
  76.             }  
  77.             Console.WriteLine("外部程序的结束运行时间:{0}",  Proc.ExitTime);  
  78.             Console.WriteLine("外部程序在结束运行时的返回值:{0}",  Proc.ExitCode);  
  79.         }  
  80.     }  
  81. }  


===============
补充几个命令:

1、!analyze -v :用于分析挂掉线程的详细情形,错误原因。

2、!locks :列出全部资源使用情况。

3、!locks -v 0x???????? :特定地址的死锁分析。

4、!thread 0x????????:特定线程详情。

5、.thread 0x????????:转到某个线程堆栈。
 


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/b2b160/archive/2009/03/03/3951782.aspx

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/458718.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 类加载机制详解

2019独角兽企业重金招聘Python工程师标准>>> 一、类加载器 类加载器&#xff08;ClassLoader&#xff09;&#xff0c;顾名思义&#xff0c;即加载类的东西。在我们使用一个类之前&#xff0c;JVM需要先将该类的字节码文件&#xff08;.class文件&#xff09;从磁盘…

Nginx+PHP实时生成不同尺寸图片

原来图片服务器采用Windows .net架构&#xff0c;鉴于需求需要生成各种尺寸图片。流程说明:用户从Nginx请求对应的图片,判断是否存在_200x300的对应参数&#xff0c;如果没有就直接请求到对应目录的原图&#xff0c;否则继续判断是否在本地已经生成了对应的缓存图片&#xff0c…

掌握VS2010调试 -- 入门指南

1 导言 在软件开发周期中&#xff0c;测试和修正缺陷&#xff08;defect&#xff0c;defect与bug的区别&#xff1a;Bug是缺陷的一种表现形式&#xff0c;而一个缺陷是可以引起多种Bug的&#xff09;的时间远多于写代码的时间。通常&#xff0c;debug是指发现缺陷并改正的过程。…

【操作系统】进程管理

进程管理 进程的基本概念 程序的顺序执行及其特征 程序的顺序执行:仅当前一操作(程序段)执行完后&#xff0c;才能执行后续操作。 程序顺序执行时的特征&#xff1a;顺序性&#xff0c;封闭性&#xff0c;可再见性。 前趋图 前趋图(Precedence Graph)是一个有向无循环图&#…

va_list va_start va_end的使用

<pre name"code" class"cpp" style"color: rgb(51, 51, 51); white-space: pre-wrap; word-wrap: break-word;"><strong>一、 从printf()开始</strong> 从大家都很熟悉的格式化字符串函数开始介绍可变参数函数。 原型&#xf…

Linux学习之CentOS(三)----将Cent0S 7的网卡名称eno16777736改为eth0

【正文】 Linux系统版本&#xff1a;CentOS_7&#xff08;64位&#xff09; 一、前言&#xff1a; 今天又从Centos 6.5装回了Centos 7&#xff0c;毕竟还是要顺应潮流嘛。安装完成之后&#xff0c;发现发现CentOS 7默认的网卡名称是eno16777736&#xff0c;如图所示&#xff1a…

数据库事务的隔离机制

数据库事务(Database Transaction) &#xff0c;是指作为单个逻辑工作单元执行的一系列操作&#xff0c;要么完全地执行&#xff0c;要么完全地不执行。----百度百科就是说你定义一组数据库操作&#xff0c;然后告诉数据库说这些操作要么都成功&#xff0c;要么都不成功。类似于…

如何使用CppUnit进行单元测试

http://www.vckbase.com/document/viewdoc/?id1762 一、前言 测试驱动开发(TDD)是以测试作为开发过程的中心&#xff0c;它坚持&#xff0c;在编写实际代码之前&#xff0c;先写好基于产品代码的测试代码。开发过程的目标就是首先使测试能够通过&#xff0c;然后再优化设计结构…

iOS开发网络篇—Reachability检测网络状态

前言&#xff1a;当应用程序需要访问网络的时候&#xff0c;它首先应该检查设备的网络状态&#xff0c;确认设备的网络环境及连接情况&#xff0c;并针对这些情况提醒用户做出相应的处理。最好能监听设备的网络状态的改变&#xff0c;当设备网络状态连接、断开时&#xff0c;程…

网络七层协议 五层模型 TCP连接 HTTP连接 socket套接字

socket&#xff08;套接字&#xff09;是通信的基石&#xff0c;是支持TCP/IP协议的网络通信的基本操作单元&#xff0c;包含进行网络通信必须的五种信息&#xff1a;连接使用的协议&#xff0c;本地主机的IP地址&#xff0c;本地进程的协议端口&#xff0c;远地主机的IP地址&a…

【VC++技术杂谈005】如何与程控仪器通过GPIB接口进行通信

在工控测试系统中&#xff0c;经常需要使用到各类程控仪器&#xff0c;这些程控仪器通常具有GPIB、LAN、USB等硬件接口&#xff0c;计算机通过这些接口能够与其通信&#xff0c;从而实现自动测量、数据采集、数据分析和数据处理等操作。本文主要介绍如何与程控仪器通过GPIB接口…

标题在上边框中的html(fieldset标签)

<fieldset> <legend>标题</legend> 内容 </fieldset> 转载于:https://www.cnblogs.com/lswbk/p/4952820.html

移除项目中的CocoaPods

在项目中移除CocoaPods cocoaPods虽然很方便&#xff0c;但是我是真心的不喜欢用它&#xff0c;总是出错如果你觉得CocoaPods让你的项目出现了问题&#xff0c;不好用甚至是恶心&#xff0c;想将其从项目中彻底移除&#xff0c;也有方法&#xff1a; 1.删除工程文件夹下的Podf…

popoverController(iPad)

一、设置尺寸 提示&#xff1a;不建议&#xff0c;像下面这样吧popover的宽度和高度写死。 1 //1.新建一个内容控制器2 YYMenuViewController *menuVc[[YYMenuViewController alloc]init];3 4 //2.新建一个popoverController&#xff0c;并设置其内容控制器5 s…

fastQC

Fastqc用途 FastQC aims to provide a simple way to do some quality control checks on raw sequence data coming from high throughput sequencing pipelines. It provides a modular set of analyses which you can use to give a quick impression of whether your data …

C++ Handle(句柄) part1

本文是我学习C&#xff0b;&#xff0b;沉思录第6章的笔记 本文主要讲述了Handle类的概念&#xff0c;定义方法以及写时复制技术。 在前文(Surrogate代理类)的讲解中我们了解到了代理的实现方法. 代理类有很多好处,但是麻烦的是每次都得进行复制.如果该类是经常使用并且member很…

Swift调用Objective C的FrameWork

很多Github的库经过很多年的发展&#xff0c;源码都是OC写的&#xff0c;&#xff0c;所以&#xff0c;用Swift调用OC的库就是开发中难免遇到的的一个问题&#xff0c;本文以AFNetworking为例&#xff0c;讲解如何跨语言调用。 第一步 创建一个空的工程 注意&#xff0c;语言选…

显式(静态)调用: LIB + DLL + .H

1、编程时用ad.h,ad.lib,放在项目当前目录里2、在头文件中加入#include "ad.h"3、在Project Setting–>Link–>Object/library modules加入ad.lib执行时将ad.dll跟你的程序放在同一目录。 就可以直接调用dll中的函数了 当前目录 转载于:https://www.cnblogs.co…

接入支付宝出现交易订单处理失败,请稍后再试(ALI64)的错误

上次在接入支付宝的时候就碰到了交易订单处理失败&#xff0c;请稍后再试&#xff08;ALI64&#xff09;这样的错误&#xff0c;后来经过排查和总结&#xff0c;一般来讲这种问题都是公钥和私钥没有正确配置造成的。支付宝这边为了保证数据在传输时不被篡改&#xff0c;使用了r…

支付宝集成交互流程

交互流程 功能流程 流程说明&#xff08;以Android平台为例&#xff09;&#xff1a; 第4步&#xff1a;调用支付接口&#xff1a;此消息就是本接口所描述的开发包提供的支付对象PayTask&#xff0c;将商户签名后的订单信息传进pay方法唤起支付宝收银台&#xff0c;订单格式具体…