<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      WinDbg+SOS:Web服務(wù)器High CPU Hang(100%)實(shí)例分析

      下午,msn上面一個(gè)朋友發(fā)了一個(gè)dump文件過來,說是Web服務(wù)器的CPU使用率在100%,找不到問題在什么地方,讓幫忙看看,遂讓把dump文件傳過來,找找問題出在哪兒。

             Framework2.0Windows 2kOS

             加載了Dump文件之后,接著加載2.0版本的SOS擴(kuò)展調(diào)試模塊:

             .load C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\SOS.dll

             習(xí)慣性的列出托管線程:

             !threads

             發(fā)現(xiàn)報(bào)告以下錯(cuò)誤:

       

      Unable to load image

      C:\WINDOWS\assembly\NativeImages_v2.0.50727_64\mscorlib\339a2c337cdafd47f2ba740bb03f9718\mscorlib.ni.dll, Win32 error 2

      *** WARNING: Unable to verify checksum for mscorlib.ni.dll

       

             lm以下,發(fā)現(xiàn)symbol文件都沒加載上來,于是.reload一下,我配置的符號文件路徑如下:

       

             C:\WINDOWS\Symbols;C:\Program Files\Microsoft Visual Studio8

      \SDK\v2.0\symbols;srv*E:\bak\symbols*http://msdl.microsoft.com/download/symbols

       

      瞟了一下網(wǎng)絡(luò)流量,30kb/s,這個(gè)時(shí)候正在從符號文件服務(wù)器上面下符號文件呢。過了一會(huì),需要的符號文件都下載好了:

      首先看看線程池里面的情況:

       

      0:000> !threadpool

      CPU utilization 100%

      Worker Thread: Total: 1 Running: 0 Idle: 1 MaxLimit: 100 MinLimit: 1

      Work Request in Queue: 0

      --------------------------------------

      Number of Timers: 8

      --------------------------------------

      Completion Port Thread:Total: 1 Free: 1 MaxFree: 2 CurrentLimit: 1 MaxLimit: 100 MinLimit: 1

       

      厄,CPU占用率果然在百分之一百啊。

      看看cpu時(shí)間的使用情況:

       

      0:000> .time

      Debug session time: Thu Jun 12 08:59:14.000 2008 (GMT+8)

      System Uptime: 2 days 1:01:08.081

      Process Uptime: 2 days 0:30:27.000

        Kernel time: 0 days 0:00:22.000

        User time: 0 days 0:09:40.000   

      嗯,主要是用戶的應(yīng)用程序把Process Time給占用了。接著就看看到底是那個(gè)線程把User ModeCPU時(shí)間都給用掉了:

       

      0:000> !runaway

       User Mode Time

        Thread       Time

        12:b9c       0 days 0:06:27.109

         2:b54       0 days 0:00:50.468

        15:f98       0 days 0:00:09.937

        10:b94       0 days 0:00:03.531

         5:b6c       0 days 0:00:01.937

        11:b98       0 days 0:00:01.671

         3:b58       0 days 0:00:01.171

         0:b44       0 days 0:00:00.640

         9:b84       0 days 0:00:00.265

         7:b7c       0 days 0:00:00.203

        14:388       0 days 0:00:00.000

        13:b68       0 days 0:00:00.000

         8:b80       0 days 0:00:00.000

         6:b78       0 days 0:00:00.000

         4:b5c       0 days 0:00:00.000

         1:b50       0 days 0:00:00.000

      User Time一共是0 days 0:09:40.000這么多時(shí)間,Thread 12一個(gè)人就占用0 days 0:06:27.109這么多時(shí)間,好吧,來看看私下到底干了什么:

       

      0:000> ~12s

      eax=000007ff ebx=00000000 ecx=0112d894 edx=013055ac esi=013055ac edi=dbb83137

      eip=051dc0be esp=06a8ef48 ebp=06a8efb4 iopl=0         nv up ei pl nz ac pe nc

      cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000216

      051dc0be 3bf8            cmp     edi,eax

       

      切換完了之后,查看調(diào)用堆棧:

       

      0:012> k

      ChildEBP RetAddr 

      WARNING: Frame IP not in any known module. Following frames may be wrong.

      06a8efb4 051d4b92 0x51dc0be

      06a8f068 03530d1f 0x51d4b92

      06a8f080 79e7c74b mscorlib_ni+0x2f0d1f

      06a8f090 79e7c6cc mscorwks!CallDescrWorker+0x33

      06a8f110 79e7c8e1 mscorwks!CallDescrWorkerWithHandler+0xa3

      06a8f24c 79e7c783 mscorwks!MethodDesc::CallDescr+0x19c

      06a8f268 79e7c90d mscorwks!MethodDesc::CallTargetWorker+0x1f

      06a8f27c 79eb300f mscorwks!MethodDescCallSite::Call_RetArgSlot+0x18

      06a8f448 79eb2f31 mscorwks!ExecuteCodeWithGuaranteedCleanupHelper+0x9b

      06a8f4f8 034f3ff7

      mscorwks!ReflectionInvocation::ExecuteCodeWithGuaranteedCleanup+0xf9

      06a8f510 034f3ede mscorlib_ni+0x2b3ff7

      06a8f528 03530c68 mscorlib_ni+0x2b3ede

      06a8f540 79e7c74b mscorlib_ni+0x2f0c68

      06a8f550 79e7c6cc mscorwks!CallDescrWorker+0x33

      06a8f5d0 79e7c8e1 mscorwks!CallDescrWorkerWithHandler+0xa3

      06a8f710 79e7c783 mscorwks!MethodDesc::CallDescr+0x19c

      06a8f72c 79e7c90d mscorwks!MethodDesc::CallTargetWorker+0x1f

      06a8f740 79fc58cd mscorwks!MethodDescCallSite::Call_RetArgSlot+0x18

      06a8f928 79ef3207 mscorwks!ThreadNative::KickOffThread_Worker+0x190

      06a8f93c 79ef31a3 mscorwks!Thread::DoADCallBack+0x32a

       

      一直到CallDescrWorker這個(gè)地方,都沒有發(fā)現(xiàn)有啥異常的,比較標(biāo)準(zhǔn)的一個(gè)初始化并且執(zhí)行特定任務(wù)的Worker Thread的調(diào)用堆棧的最開始的部分,比較正常的說。然后就剩下stack的頂部的兩個(gè)調(diào)用:

       

      06a8efb4 051d4b92 0x51dc0be

      06a8f068 03530d1f 0x51d4b92

       

      這個(gè)沒有顯示到底是什么方法,好吧,用SOS的列出托管方法調(diào)用堆棧看看:

       

      0:012> !clrstack

      OS Thread Id: 0xb9c (12)

      ESP       EIP    

      06a8ef48 051dc0be RSWebGis.RSProtocolClass.GetDataLong(Byte[], Int32)

      06a8ef68 051dbf74 RSWebGis.RSProtocolClass.ParsePackage(Byte[])

      06a8efbc 051d4b92 RSWebGis.RSProtocolClass.DoAnalysisWork()

      06a8f070 03530d1f System.Threading.ThreadHelper.ThreadStart_Context(System.Object)

      06a8f078 034f40ab System.Threading.ExecutionContext.runTryCode(System.Object)

      06a8f49c 79e7c74b [HelperMethodFrame_PROTECTOBJ: 06a8f49c]

      System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode, CleanupCode, System.Object)

      06a8f504 034f3ff7

      System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)

      06a8f51c 034f3ede

      System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)

      06a8f534 03530c68 System.Threading.ThreadHelper.ThreadStart()

      06a8f760 79e7c74b [GCFrame: 06a8f760]

      06a8fa50 79e7c74b [ContextTransitionFrame: 06a8fa50]

       

      這個(gè)時(shí)候,最上面的三行調(diào)用估計(jì)就是問題的關(guān)鍵所在了。依照以往的經(jīng)驗(yàn),有幾種性能調(diào)試的時(shí)候的現(xiàn)象比較常見:

      l         CPU使用率高,內(nèi)存使用率不高

      l         CPU使用率高,內(nèi)存某個(gè)模塊或者線程占用比較離譜

      l         CPU和內(nèi)存使用都不高,就是網(wǎng)頁打開特別慢

      對這幾個(gè)現(xiàn)象一般出現(xiàn)問題的大致原因和一個(gè)常用的分析套路,大致問題會(huì)出現(xiàn)在哪兒,了解下對這個(gè)時(shí)候的判斷還是比較有用的。:)

       

      單從上面的調(diào)用堆棧來看,應(yīng)該是代碼里面寫的程序出現(xiàn)了問題,好吧,老娘是好欺負(fù)的么?

      把一個(gè)module從一個(gè)dump文件里面分離出來的語法:

       

      !SaveModule <Base address> <Filename>

      <Base address>可以有好些辦法都可以得到,可以使用dumpDomain命令查看在AppDomain里面查看加載了哪些Module,下面是截取!DumpDomain的一條記錄,根據(jù)上面的堆棧顯示,就找RSWebGis這個(gè)模塊:

       

      Assembly: 001de3d0 [c:\WINNT\Microsoft.NET\Framework\v2.0.50727\Temporary

      ASP.NETFiles\rswebgis\cbfaa214\c8518bb9\assembly\dl3\b000bb67\

      2dae9f2e_ab93c801\RSWebGis.DLL

      ClassLoader: 001dc518

      SecurityDescriptor: 001de348

        Module Name

      05860010 c:\WINNT\Microsoft.NET\Framework\v2.0.50727\Temporary

      ASP.NET Files\rswebgis\cbfaa214\c8518bb9\assembly\dl3\b000bb67\

      2dae9f2e_ab93c801\RSWebGis.DLL

       

      這里的05860010就是RSWebGis這個(gè)模塊的base地址。當(dāng)然,這個(gè)base Address還可以通過lm命令查看加載的module來獲取。

      好吧,剝離出來保存到C盤:

       

      0:000>!SaveModule 05880000 c:\ RSWebGis.DLL.dll

      4 sections in file

      section 0 - VA=1000, VASize=e82da9, FileAddr=400, FileSize=e82e00

      section 1 - VA=e84000, VASize=24d24, FileAddr=e83200, FileSize=ec00

      section 2 - VA=ea9000, VASize=5a8, FileAddr=e91e00, FileSize=600

      section 3 - VA=eaa000, VASize=c183c, FileAddr=e92400, FileSize=c1a00

      一共4個(gè)section,全部剝奪了出來。

       

      抄起Reflector反編譯,首先找到

      06a8ef48 051dc0be RSWebGis.RSProtocolClass.GetDataLong(Byte[], Int32)

      這個(gè)的實(shí)現(xiàn):

       

      private int GetDataLong(byte[] bytes, int count)

      {

          if ((((count > (bytes.Length - 1)) || (count > (bytes.Length - 2))) || ((count >(bytes.Length - 3)) || (count > (bytes.Length - 4)))) || (count < 0))

          {

              return 0;

          }

          return BitConverter.ToInt32(bytes, count);

      }

      我的個(gè)天,這個(gè)括號怎么這么多,我看的叫一個(gè)眼花。最開始的時(shí)候,估計(jì)問題是在這個(gè)地方,出現(xiàn)了邏輯錯(cuò)誤,瞅了半天,也找不到個(gè)所以然,這判斷也沒啥問題啊,就是幾個(gè)括號致使和正常的判斷邏輯有點(diǎn)偏差,但是也不至于是百分之一百的CPU占用率啊,然后問zhaochangj兄要這個(gè)方法的程序代碼,結(jié)果發(fā)現(xiàn)是:

       

      #region 從字節(jié)數(shù)組中從指定的位置開始取一個(gè)長整型

              /// <summary>

              /// 取得數(shù)據(jù)包的大小

              /// </summary>

              /// <param name="bytes">指定的數(shù)據(jù)包</param>

              /// <param name="count">起始位置</param>

              private int GetDataLong(byte[] bytes, int count)

              {

                  if (count > bytes.Length - 1 || count > bytes.Length - 2 || count > bytes.Length - 3

      || count > bytes.Length - 4 || count < 0)

        

      看來這個(gè)Reflector對付這種很多括號的時(shí)候,厄,會(huì)有點(diǎn)短路。

      好吧,既然這個(gè)沒有問題,就看上面是如何調(diào)用這個(gè)的:

       

      private void ParsePackage(byte[] byteData)

      {

          int dataLong;

          int length = byteData.Length;

          for (int i = 0; i < length; i += dataLong)

          {

              dataLong = this.GetDataLong(byteData, i);

              if (((i + dataLong) <= length) && (dataLong > 0))

              {

                  long num4;

                  int num5;

                  int num6;

                  string str;

                  byte[] buffer;

                  byte[] buffer2;

                  this.CopyBytes(byteData, i, dataLong, out buffer2);

                  int start = 0;

                  if (((buffer2.Length - start) >= 15) && (this.TCPMsgHeadProc(buffer2, start,

      out num4, out num5, out str, out num6, out buffer) == 0L))

                  {

                      this.m_noBackCount = 0;

                      this.TCPDataProc(num4, num5, str, num6, buffer);

                  }

              }

          }

      }

       

      厄,看到了for循環(huán),呵呵,特別需要注意下,當(dāng)前這種情況很多時(shí)候都可能是特定情況下的死循環(huán),當(dāng)然,不是全部。

       

       正在納悶這個(gè)定義的dataLong變量,第一次使用的時(shí)候是沒賦值的,這樣編譯器是有錯(cuò)誤提示的啊,而且i += dataLong這種寫法是第一次在for循環(huán)里面看到遂上msn問問zhaochangj這段代碼是做啥用的,然后發(fā)過來了這個(gè)函數(shù)的這段源碼:

       

      while (offSet < bytesTotal)

      {

      int length = GetDataLong(byteData, offSet);

      byte[] tmpMsg;

      if ((offSet + length <= bytesTotal) && (length > 0))

      {

      //

                   

      終于問題找到了:如果GetDataLong這個(gè)方法的返回值是0的時(shí)候,就會(huì)導(dǎo)致循環(huán)一直繼續(xù)下去,也就是for (int i = 0; i < length; i += dataLong)在程序的時(shí)候,如果dataLong返回的是0,也就是格式化一個(gè)長度小于4byte串的時(shí)候,循環(huán)就會(huì)一直繼續(xù)下去。

       

      Sum:這里只是描述了網(wǎng)站在發(fā)布以后,由CPU和內(nèi)存以及訪問速度出現(xiàn)特別慢的情況下徒手Windbg找問題的大致思路,具體情況具體問題可能啥樣都有,具體問題具體對待吧。

       

      2008-6-17 11:30:20 PM 首發(fā)sscli.cnblogs.com & debug.cnblogs.com

       

      posted on 2008-06-17 23:36  lbq1221119  閱讀(4465)  評論(25)    收藏  舉報(bào)

      導(dǎo)航

      主站蜘蛛池模板: 亚洲成aⅴ人片久青草影院| 又湿又紧又大又爽A视频男| 色香欲天天影视综合网| 国产午夜影视大全免费观看| 小嫩批日出水无码视频免费| 少妇又爽又刺激视频| 久久99久久99精品免视看国产成人| 国产三级精品三级在线看| 久久国内精品一区二区三区| 激情在线网| 亚洲码国产精品高潮在线| 日韩精品一区二区三区在线观看| 日本成人午夜一区二区三区 | 成人精品自拍视频免费看| 亳州市| 亚洲一区二区三区人妻天堂| 国产福利社区一区二区| 国偷自产一区二区三区在线视频| 久热天堂在线视频精品伊人| 国产91精品调教在线播放| 久久久久人妻精品一区三寸| 国产亚洲精品久久久网站好莱| 91精品国产一二三产区| 国产午精品午夜福利757视频播放 国产午夜亚洲精品国产成人 | 国产精品成人久久电影| 无码伊人66久久大杳蕉网站谷歌| 亚洲另类无码一区二区三区 | 极品蜜桃臀一区二区av| 国产在线自拍一区二区三区| 国产香蕉97碰碰久久人人| 国产久免费热视频在线观看| 丰满的熟妇岳中文字幕| 国产亚洲精品VA片在线播放 | 一亚洲一区二区中文字幕| 在线a亚洲老鸭窝天堂| 亚洲2017天堂色无码| av新版天堂在线观看| 午夜精品久久久久久99热| 蜜臀av一区二区三区日韩| 国产suv精品一区二区33| 欧美一区二区三区激情|