{"id":4716,"date":"2013-08-12T16:56:40","date_gmt":"2013-08-12T15:56:40","guid":{"rendered":"http:\/\/blog.capdata.fr\/?p=4716"},"modified":"2019-09-13T14:00:01","modified_gmt":"2019-09-13T13:00:01","slug":"retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler","status":"publish","type":"post","link":"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/","title":{"rendered":"Retrouver la fonction \u00e0 l&#8217;origine d&#8217;un Non Yielding IOCP Listener"},"content":{"rendered":"<a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F4716&#038;text=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/twitter.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F4716&#038;title=Retrouver%20la%20fonction%20%C3%A0%20l%E2%80%99origine%20d%E2%80%99un%20Non%20Yielding%20IOCP%20Listener\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/linkedin.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=Retrouver%20la%20fonction%20%C3%A0%20l%E2%80%99origine%20d%E2%80%99un%20Non%20Yielding%20IOCP%20Listener&#038;body=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20:%20https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F4716\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/mail.png\" \/><\/a><p>Petit m\u00e9mento pour retrouver la fonction \u00e0 l&#8217;origine d&#8217;un SOS non yielding ou un IOCP non yielding. On va en profiter pour rappeler les conditions de d\u00e9tection des deux ph\u00e9nom\u00e8nes. On part sur une version &gt;= 2005.<\/p>\n<p>Pour m\u00e9moire, cette condition de &#8220;non-rel\u00e2che&#8221; (non-yielding) d&#8217;un scheduler ou d&#8217;un IO Completion Port a \u00e9t\u00e9 impl\u00e9ment\u00e9e en SQL Server 2000 SP3 \u00e0 la demande du support, pour permettre de diagnostiquer plus facilement les cas o\u00f9 une fonction bloque un scheduler (qui fonctionne depuis SQL 7.0 dans un mode coop\u00e9ratif rappelons-le). Depuis SQL Server 2005, un thread syst\u00e8me a la charge de d\u00e9tecter ces conditions, le Scheduler Monitor.<\/p>\n<h2>Erreur 17883, non-yielding Scheduler :<\/h2>\n<p>Depuis SQL Server 2005, le Scheduler Monitor se r\u00e9veille toutes les 5 secondes et lance un check simple (un genre de LooksAlive). Si l&#8217;ensemble des hypoth\u00e8ses suivantes sont v\u00e9rifi\u00e9es:<\/p>\n<p>&#8211; Le scheduler n&#8217;est pas idle (il travaille quoi&#8230;)<br \/>\n&#8211; Le nombre de yields n&#8217;a pas \u00e9volu\u00e9 depuis le dernier contr\u00f4le<br \/>\n&#8211; Le worker actif n&#8217;est pas d\u00e9j\u00e0 dans une exception ou en train de g\u00e9n\u00e9rer un minidump.<\/p>\n<p>&#8230; alors le scheduler est consid\u00e9r\u00e9 comme potentiellement bloqu\u00e9, et un contr\u00f4le un peu plus pouss\u00e9 va suivre (genre de isAlive). Si le worker accumule 10 secondes sans avoir boug\u00e9 (donc cons\u00e9cutivement \u00e0 2 checks simples), le Scheduler Monitor va v\u00e9rifier si la somme des temps (kernel + user) accumul\u00e9s par le worker depuis le d\u00e9but de son ex\u00e9cution:<\/p>\n<p><strong>&#8211; Est inf\u00e9rieure ou \u00e9gale \u00e0 5% au temps total instance<\/strong> (report\u00e9 dans sys.dm_os_sys_info): d\u00e9signe typiquement les cas o\u00f9 le worker est coinc\u00e9 en attente du retour d&#8217;une API externe (exemple typique, WriteFileGather() sur un filesystem encrypt\u00e9 ou compress\u00e9, le filter driver de l&#8217;antivirus qui retarde l&#8217;IO, ou les outils d&#8217;encryption 3rd party, le chemin vers la baie qui est en \u00e9chec &#8230;)<br \/>\n<strong>&#8211; Est sup\u00e9rieure ou \u00e9gale \u00e0 40% du temps total instance <\/strong>[1]: d\u00e9signe typiquement les cas o\u00f9 le worker est dans une boucle infinie (cas fr\u00e9quents avec de l&#8217;ex\u00e9cution SQLCLR).<br \/>\n<strong>&#8211; Et que tous les schedulers ne sont pas \u00e0 100% de charge<\/strong> (donc qu&#8217;il y a des cycles sous le coude)<\/p>\n<p>Alors le scheduler est d\u00e9finitivement consid\u00e9r\u00e9 comme bloqu\u00e9 et le callback de capture va se mettre en place. Au bout de 60 secondes o\u00f9 la condition de non-yield est maintenue, un minidump (*.mdmp) contenant la stack de tous les threads est captur\u00e9 par SQLDumper sous ~MSSQL\\Log. Il ne contient pas tout l&#8217;espace m\u00e9moire allou\u00e9, ce qui serait en 64 bits franchement impraticable, c&#8217;est pour \u00e7a que \u00e7a s&#8217;appelle un minidump. Ca veut dire aussi qu&#8217;on ne verra pas n\u00e9cessairement tout dans le dump.<\/p>\n<p>Il est important de noter que le minidump ne sera pris qu&#8217;une seule fois, m\u00eame si la condition persiste au del\u00e0 des 60 secondes. Il faudra soit utiliser le TF 1262 ou red\u00e9marrer l&#8217;instance pour r\u00e9armer la condition. En outre, si \u00e0 l&#8217;installation vous avez coch\u00e9 les cases &#8216;Watson&#8217; (error reporting), le minidump sera envoy\u00e9 \u00e0 un des serveurs de reporting de MS.<\/p>\n<p>[1] <strong>Note<\/strong>: si la valeur se trouve entre 5 et 40%, on consid\u00e8re que le worker est victime de facteurs externes (pagination, autres processes avec une priorit\u00e9 plus \u00e9lev\u00e9e) et un minidump dans ce cas ne sert \u00e0 rien.<\/p>\n<p>Dans l&#8217;ERRORLOG, une belle stack trace:<\/p>\n<pre name=\"code\" class=\"sql\">2011-07-24 22:17:45.850 Server\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 * BEGIN STACK DUMP:\r\n2011-07-24 22:17:45.850 Server\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 *\u00a0\u00a0 07\/24\/11 22:17:45 spid 2388\r\n2011-07-24 22:17:45.850 Server\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 *\r\n2011-07-24 22:17:45.850 Server\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 * Non-yielding Scheduler \r\n2011-07-24 22:17:45.850 Server\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Stack Signature for the dump is 0x00000000000003B6\r\n2011-07-24 22:17:53.380 Server\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 External dump process return code 0\u00d720000001.\r\n(...)<\/pre>\n<h2>Erreur\u00a0 17887, non yielding IOCP\u00a0 Listener:<\/h2>\n<p>Un IO Completion Port est un outil fourni par l&#8217;API win32 pour g\u00e9rer efficacement les entr\u00e9es sorties asynchrones (cf article sur les <a href=\"http:\/\/blog.capdata.fr\/index.php\/io-asynchrones-episode-1\/\">IO asynchrones<\/a>). Dans SQL Server il sert \u00e0 g\u00e9rer les demandes de connexion.<\/p>\n<p>Cette condition a \u00e9t\u00e9 ajout\u00e9e avec la version SQL Server 2005 pour d\u00e9tecter les cas o\u00f9 l&#8217;IOCP est bloqu\u00e9 et ne peut plus g\u00e9rer de nouvelles demandes de connexion. L&#8217;ensemble des hypoth\u00e8ses suivantes doivent \u00eatre r\u00e9unies pour valider la condition d&#8217;IOCP bloqu\u00e9:<\/p>\n<p>&#8211; Un IOCP est actif<br \/>\n&#8211; Pas de nouvelle demande n&#8217;a \u00e9t\u00e9 post\u00e9e sur le port depuis le dernier check (toutes les 5 secondes)<br \/>\n&#8211; La situation persiste depuis au moins 10 secondes (donc deux checks basiques comme pour l&#8217;erreur 17883).<br \/>\n&#8211; SQL Server n&#8217;est ni sous pression CPU ni sous pression m\u00e9moire.<\/p>\n<p>Dans ces conditions, un minidump est captur\u00e9 exactement comme pour l&#8217;erreur 17883. Et l\u00e0 aussi une belle stack trace :<\/p>\n<pre name=\"code\" class=\"sql\">2013-08-08 16:05:41.93 Server\u00a0\u00a0\u00a0\u00a0\u00a0 Using 'dbghelp.dll' version '4.0.5'\r\n2013-08-08 16:05:42.08 Server\u00a0\u00a0\u00a0\u00a0\u00a0 **Dump thread - spid = 0, EC = 0x0000000000000000\r\n2013-08-08 16:05:42.09 Server\u00a0\u00a0\u00a0\u00a0\u00a0 ***Stack Dump being sent to K:\\MSSQL10_50.MSSQLSERVER\\MSSQL\\LOG\\SQLDump0001.txt\r\n2013-08-08 16:05:42.09 Server\u00a0\u00a0\u00a0\u00a0\u00a0 * *******************************************************************************\r\n2013-08-08 16:05:42.09 Server\u00a0\u00a0\u00a0\u00a0\u00a0 *\r\n2013-08-08 16:05:42.09 Server\u00a0\u00a0\u00a0\u00a0\u00a0 * BEGIN STACK DUMP:\r\n2013-08-08 16:05:42.09 Server\u00a0\u00a0\u00a0\u00a0\u00a0 *\u00a0\u00a0 08\/08\/13 16:05:42 spid 1996\r\n2013-08-08 16:05:42.09 Server\u00a0\u00a0\u00a0\u00a0\u00a0 *\r\n2013-08-08 16:05:42.09 Server\u00a0\u00a0\u00a0\u00a0\u00a0 * Non-yielding IOCP Listener\r\n2013-08-08 16:05:42.09 Server\u00a0\u00a0\u00a0\u00a0\u00a0 *\r\n2013-08-08 16:05:42.09 Server\u00a0\u00a0\u00a0\u00a0\u00a0 * *******************************************************************************\r\n2013-08-08 16:05:42.09 Server\u00a0\u00a0\u00a0\u00a0\u00a0 * -------------------------------------------------------------------------------\r\n2013-08-08 16:05:42.09 Server\u00a0\u00a0\u00a0\u00a0\u00a0 * Short Stack Dump\r\n2013-08-08 16:05:42.32 Server\u00a0\u00a0\u00a0\u00a0\u00a0 Stack Signature for the dump is 0x0000000000000056\r\n2013-08-08 16:06:04.10 Server\u00a0\u00a0\u00a0\u00a0\u00a0 External dump process return code 0x20000001.\r\nExternal dump process returned no errors.\r\n\r\n2013-08-08 16:06:04.10 Logon\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Error: 17803, Severity: 20, State: 17.\r\n2013-08-08 16:06:04.10 Logon\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 There was a memory allocation failure during connection establishment. Reduce nonessential\r\nmemory load, or increase system memory. The connection has been closed. [CLIENT: 194.26.22.110]<\/pre>\n<p>Une ligne est particuli\u00e8rement int\u00e9ressante:<\/p>\n<pre name=\"code\" class=\"sql\">2013-08-08 16:06:04.13 Server\u00a0\u00a0\u00a0\u00a0\u00a0 IO Completion Listener (0xce8) Worker 0x00000000006AE1A0 appears to be non-yielding on\r\nNode 0. Approx CPU Used: kernel 46 ms, user 9609 ms, Interval: 14999.\r\n2013-08-08 16:06:59.65 spid88<\/pre>\n<p>O\u00f9 <strong>0xce8<\/strong> d\u00e9signe le ThreadID de notre bloquant.<\/p>\n<h2>Exemple avec une 17887:<\/h2>\n<p>Pour ouvrir le minidump, il faut utiliser <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/windows\/hardware\/gg463009.aspx\">windbg <\/a>et d\u00e9clarer les symboles dans la bonne version de SQL Server soit en d\u00e9clarant le serveur de symboles de MS comme d\u00e9crit dans l&#8217;article sur <a href=\"http:\/\/blog.capdata.fr\/index.php\/consistence-des-ecritures-avec-sata\/\">SATA<\/a>, soit en r\u00e9cup\u00e9rant le PDB de sqlservr comme d\u00e9crit par Paul Randal <a href=\"http:\/\/www.sqlskills.com\/blogs\/paul\/how-to-download-a-sqlservr-pdb-symbol-file\/\">ici<\/a>.<\/p>\n<p>La particularit\u00e9 du minidump dans ce cas, est qu&#8217;il contient outre la stack de tous les threads, une copie de la structure <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms679284%28VS.85%29.aspx\">CONTEXT <\/a>du thread qui bloque au moment pr\u00e9cis o\u00f9 l&#8217;exception est lev\u00e9e, qui sera accessible dans le debugger via la commande<em> .cxr<\/em>. CONTEXT contient la valeur des registres du CPU sur lequel notre bloqueur \u00e9tait en ex\u00e9cution, et nous informe sur la stack exacte impliqu\u00e9e dans notre probl\u00e8me, car parfois la situation peut se d\u00e9bloquer entre le moment o\u00f9 l&#8217;exception est d\u00e9tect\u00e9e et le minidump g\u00e9n\u00e9r\u00e9. La stack du thread ne serait alors plus valide, voire plus disponible du tout. Ca permet aussi de v\u00e9rifier si le worker n&#8217;a pas progress\u00e9 au dernier moment.<\/p>\n<p>Alors on y va, on lance windbg,\u00a0 et on charge le minidump File -&gt; Open Crash Dump &#8230;<\/p>\n<pre name=\"code\" class=\"sql\">Loading Dump File [E:\\SQLDump0001.mdmp]\r\nComment: 'Stack Trace'\r\nComment: 'Non-yielding IOCP Listener'\r\nUser Mini Dump File: Only registers, stack and portions of memory are available\r\n\r\nSymbol search path is: SRV*e:\\symbols*http:\/\/msdl.microsoft.com\/download\/symbols;E:\\Symbols;E:\\DENALI\\MSSQL11.DENALI\\MSSQL\\Binn\r\nExecutable search path is:\r\nWindows 7 Version 7601 (Service Pack 1) MP (2 procs) Free x64\r\nProduct: Server, suite: Enterprise TerminalServer SingleUserTS\r\nMachine Name:\r\nDebug session time: Thu Aug\u00a0 8 15:06:03.000 2013 (UTC + 2:00)\r\nSystem Uptime: 20 days 20:56:11.890\r\nProcess Uptime: 8 days 3:28:59.000\r\n................................................................\r\n.....................................................\r\nLoading unloaded module list\r\n.....................................................................\r\nThis dump file has an exception of interest stored in it.\r\nThe stored exception information can be accessed via .ecxr.\r\n(a44.7cc): Unknown exception - code 00000000 (first\/second chance not available)\r\nntdll!NtWaitForSingleObject+0xa:\r\n00000000`77c3135a c3\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ret<\/pre>\n<p>On va aller chercher la derni\u00e8re stack de notre worker bloquant. On prend le contexte courant du thread 0xce8 (ThreadID = 3304):<\/p>\n<pre name=\"code\" class=\"sql\">0:006&gt; ~~[0xce8]s\r\nsqlservr!BufferPartition::Steal+0x2d:\r\n00000000`00a4da41 0f85b5100900\u00a0\u00a0\u00a0 jne\u00a0\u00a0\u00a0\u00a0 sqlservr!BufferPartition::Steal+0x2f (00000000`00adeafc) [br=0]<\/pre>\n<p>Et on affiche la stack:<\/p>\n<pre name=\"code\" class=\"sql\">0:005&gt; k\r\nChild-SP\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 RetAddr\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Call Site\r\n00000000`067aeb30 00000000`00a4dc19 sqlservr!BufferPartition::Steal+0x2d\r\n00000000`067aeb70 00000000`00a4e730 sqlservr!BPool::Steal+0x16f\r\n00000000`067aec40 00000000`00a4e330 sqlservr!SQLSinglePageAllocator::AllocatePages+0x30\r\n00000000`067aec70 00000000`00a4e537 sqlservr!MemoryNode::AllocatePagesInternal+0xfc\r\n00000000`067aef10 00000000`00a4e7e1 sqlservr!MemoryClerkInternal::AllocatePages+0xaa\r\n00000000`067aef60 00000000`00a4e77b sqlservr!CVarPageMgr::PviNewVarPage+0x41\r\n00000000`067aefd0 00000000`00a36fe9 sqlservr!CVarPageMgr::PbAllocate+0x161\r\n00000000`067af010 00000000`00e3d5cd sqlservr!CMemObj::Alloc+0x49\r\n00000000`067af050 00000000`00e3d39c sqlservr!CErrorReportingManager::CwchFormatToBuffer+0x253\r\n00000000`067af1b0 00000000`00e6bba1 sqlservr!CErrorReportingManager::CwchCallFormatToBuffer+0x18\r\n00000000`067af1f0 00000000`02acecc2 sqlservr!CLoginClientInfo::CLoginClientInfo+0x61\r\n00000000`067af270 00000000`0107e3a4 sqlservr!ReportLoginFailureBySNIConn+0x5a\r\n00000000`067af360 00000000`026cb3a3 sqlservr!TDSSNIClient::AcceptCommon+0x3f2\r\n00000000`067af660 00000000`00a7daf2 sqlservr!Smux::ReadDone+0x413\r\n00000000`067af700 00000000`00a7dc11 sqlservr!SNIReadDone+0xa2\r\n00000000`067af770 00000000`00a3bbd8 sqlservr!SOS_Node::ListenOnIOCompletionPort+0x263\r\n00000000`067af900 00000000`00a3b8ba sqlservr!SOS_Task::Param::Execute+0x12a\r\n00000000`067afa10 00000000`00a3b6ff sqlservr!SOS_Scheduler::RunTask+0x96\r\n00000000`067afa70 00000000`00f58fb6 sqlservr!SOS_Scheduler::ProcessTasks+0x128\r\n00000000`067afae0 00000000`00f59175 sqlservr!SchedulerManager::WorkerEntryPoint+0x2b6\r\n00000000`067afbc0 00000000`00f59839 sqlservr!SystemThread::RunWorker+0xcc\r\n00000000`067afc00 00000000`00f59502 sqlservr!SystemThreadDispatcher::ProcessWorker+0x2db\r\n00000000`067afcb0 00000000`755937d7 sqlservr!SchedulerManager::ThreadEntryPoint+0x173\r\n00000000`067afd50 00000000`75593894 msvcr80!endthreadex+0x47\r\n00000000`067afd80 00000000`77ad652d msvcr80!endthreadex+0x104\r\n00000000`067afdb0 00000000`77c0c521 kernel32!BaseThreadInitThunk+0xd\r\n00000000`067afde0 00000000`00000000 ntdll!RtlUserThreadStart+0x1d<\/pre>\n<p>On voit qu&#8217;on est bien sur un bon probl\u00e8me m\u00e9moire, d&#8217;apr\u00e8s les derniers appels (SQLSinglePageAllocator::AllocatePages(), BPool:Steal(), BufferPartition::Steal() ). Plus haut dans la stack, on voit les appels vers SNI (connexions r\u00e9seau): SOS_Node::ListenOnIOCompletionPort(), SNIReadDone(), Smux::ReadDone(), TDSSNIClient::AcceptCommon() &#8230; On ne peut pas vraiment en dire plus \u00e0 ce niveau l\u00e0.<\/p>\n<p>Quand au contenu de la structure CONTEXT au moment de l&#8217;exception, il va falloir faire une petite gymnastique pour retrouver le bon offset. On sait juste que la structure CONTEXT est copi\u00e9e dans une autre structure appel\u00e9e g_copiedStackInfo par SQLDumper. On va chercher o\u00f9 se trouve cette structure dans le minidump en utilisant la commande explore (&#8216;x&#8217;):<\/p>\n<pre name=\"code\" class=\"sql\">0:005&gt; x sqlservr!g_copiedStackInfo\r\n00000000`04036900 sqlservr!g_copiedStackInfo = &lt;no type information&gt;<\/pre>\n<p>Si on regarde dans winnt.h la d\u00e9finition de CONTEXT:<\/p>\n<pre name=\"code\" class=\"sql\">typedef struct _CONTEXT\r\n{\r\nDWORD\u00a0\u00a0 ContextFlags;\r\n\r\n\/* These are selected by CONTEXT_DEBUG_REGISTERS *\/\r\nDWORD\u00a0\u00a0 Dr0;\r\nDWORD\u00a0\u00a0 Dr1;\r\nDWORD\u00a0\u00a0 Dr2;\r\nDWORD\u00a0\u00a0 Dr3;\r\nDWORD\u00a0\u00a0 Dr6;\r\nDWORD\u00a0\u00a0 Dr7;\r\n\r\n\/* These are selected by CONTEXT_FLOATING_POINT *\/\r\nFLOATING_SAVE_AREA FloatSave;\r\n\r\n\/* These are selected by CONTEXT_SEGMENTS *\/\r\nDWORD\u00a0\u00a0 SegGs;\r\nDWORD\u00a0\u00a0 SegFs;\r\nDWORD\u00a0\u00a0 SegEs;\r\nDWORD\u00a0\u00a0 SegDs;\r\n\r\n\/* These are selected by CONTEXT_INTEGER *\/\r\nDWORD\u00a0\u00a0 Edi;\r\nDWORD\u00a0\u00a0 Esi;\r\nDWORD\u00a0\u00a0 Ebx;\r\nDWORD\u00a0\u00a0 Edx;\r\nDWORD\u00a0\u00a0 Ecx;\r\nDWORD\u00a0\u00a0 Eax;\r\n\r\n\/* These are selected by CONTEXT_CONTROL *\/\r\nDWORD\u00a0\u00a0 Ebp;\r\nDWORD\u00a0\u00a0 Eip;\r\nDWORD\u00a0\u00a0 SegCs;\r\nDWORD\u00a0\u00a0 EFlags;\r\nDWORD\u00a0\u00a0 Esp;\r\nDWORD\u00a0\u00a0 SegSs;\r\n\r\nBYTE\u00a0\u00a0\u00a0 ExtendedRegisters[MAXIMUM_SUPPORTED_EXTENSION];\r\n} CONTEXT;<\/pre>\n<p>Chaque propri\u00e9t\u00e9 est un DWORD, donc un <a href=\"http:\/\/www.windbg.info\/doc\/1-common-cmds.html\">dd <\/a>pour lire le contenu doit suffire:<\/p>\n<pre name=\"code\" class=\"sql\">0:005&gt; dd sqlservr!g_copiedStackInfo\r\n00000000`04036900\u00a0 00000001 00000000 069ef240 00000000\r\n00000000`04036910\u00a0 000015e0 00000000 00000000 00000000\r\n00000000`04036920\u00a0 00000000 00000000 00000000 00000000\r\n00000000`04036930\u00a0 00000000 00000000 00000000 00000000\r\n00000000`04036940\u00a0 00000000 00000000 00000000 00000000\r\n00000000`04036950\u00a0 0010000b 00001fa0 00000033 00000000\r\n00000000`04036960\u00a0 002b0000 00000297 00000000 00000000\r\n00000000`04036970\u00a0 00000000 00000000 00000000 00000000<\/pre>\n<p>Chaque ligne repr\u00e9sente une structure CONTEXT. Il faut trouver laquelle est la bonne, malheureusement je n&#8217;ai pas les symboles priv\u00e9s donc je ne vais pas pouvoir r\u00e9soudre le contenu de g_copiedStackInfo, comme me l&#8217;indique ce message laconique de windbg:<\/p>\n<pre name=\"code\" class=\"sql\">0:005&gt; dt 00000000`04036900 CONTEXT Rip Rsp Rbp\r\n*************************************************************************\r\n***\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0 Either you specified an unqualified symbol, or your debugger\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0 doesn't have full symbol information.\u00a0 Unqualified symbol\u00a0\u00a0\u00a0\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0 resolution is turned off by default. Please either specify a\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0 fully qualified symbol module!symbolname, or enable resolution ***\r\n***\u00a0\u00a0\u00a0 of unqualified symbols by typing \".symopt- 100\". Note that\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0 enabling unqualified symbol resolution with network symbol\u00a0\u00a0\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0 server shares in the symbol path may cause the debugger to\u00a0\u00a0\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0 appear to hang for long periods of time when an incorrect\u00a0\u00a0\u00a0\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0 symbol name is typed or the network symbol server is down.\u00a0\u00a0\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0 For some commands to work properly, your symbol path\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0 must point to .pdb files that have full type information.\u00a0\u00a0\u00a0\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0 Certain .pdb files (such as the public OS symbols) do not\u00a0\u00a0\u00a0\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0 contain the required information.\u00a0 Contact the group that\u00a0\u00a0\u00a0\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0 provided you with these symbols if you need this command to\u00a0\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0 work.\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0 Type referenced: CONTEXT\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ***\r\n***\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ***\r\n*************************************************************************\r\nSymbol CONTEXT not found.<\/pre>\n<p>Donc il va falloir charger les contextes\u00a0 un par un pour voir s&#8217;il y a qq chose dedans:<\/p>\n<pre name=\"code\" class=\"sql\">0:005&gt; .cxr sqlservr!g_copiedStackInfo\r\nrax=0000000000000000 rbx=0000000000000000 rcx=0000000000000000\r\nrdx=0000000000000000 rsi=0000000003b82080 rdi=0000000003b80800\r\nrip=0000000000070fc0 rsp=000000000007ffc7 rbp=0000000003b80800\r\nr8=00000000069ef240\u00a0 r9=00000000008b1080 r10=0000000003b82080\r\nr11=0000000000000001 r12=0000000000007628 r13=aaaaaaaaaaaaaaab\r\nr14=00000000008b0080 r15=000000000000005e\r\niopl=0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 nv up di pl nz na pe nc\r\ncs=0000\u00a0 ss=0000\u00a0 ds=0000\u00a0 es=0000\u00a0 fs=0000\u00a0 gs=0000\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 efl=00000000\r\n00000000`00070fc0 0000\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 add\u00a0\u00a0\u00a0\u00a0 byte ptr [rax],al ds:00000000`00000000=??\r\n0:005&gt; kc\r\n*** Stack trace for last set context - .thread\/.cxr resets it\r\nCall Site\r\n0x0<\/pre>\n<p>Nada. Frame suivante (qui se situe \u00e0 l&#8217;adresse de base + 0x10 =&gt; ( 00000000`04036910 &#8211; 00000000`04036900 ) ):<\/p>\n<pre name=\"code\" class=\"sql\">0:005&gt; .cxr sqlservr!g_copiedStackInfo+0x10\r\nrax=0000000000000000 rbx=0000000003b80800 rcx=0000000000000000\r\nrdx=000000000007ffc7 rsi=00000000069ef240 rdi=00000000008b1080\r\nrip=0000000000070fc0 rsp=0000000003b82080 rbp=0000000003b80800\r\nr8=0000000003b82080\u00a0 r9=0000000000000001 r10=0000000000007628\r\nr11=aaaaaaaaaaaaaaab r12=00000000008b0080 r13=000000000000005e\r\nr14=0000000000070fc0 r15=0000000161ffd000\r\niopl=1\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ov dn ei ng nz na pe nc\r\ncs=0000\u00a0 ss=0010\u00a0 ds=0000\u00a0 es=0000\u00a0 fs=0000\u00a0 gs=000b\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 efl=00001fa0\r\n00000000`00070fc0 0000\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 add\u00a0\u00a0\u00a0\u00a0 byte ptr [rax],al ds:00000000`00000000=??\r\n0:005&gt; kc\r\n*** Stack trace for last set context - .thread\/.cxr resets it\r\nCall Site\r\n0x0\r\n0x0<\/pre>\n<p>Toujours rien. Allons voir \u00e0 l&#8217;adresse suivante:<\/p>\n<pre name=\"code\" class=\"sql\">0:005&gt; .cxr sqlservr!g_copiedStackInfo+0x20\r\nrax=000000000007ffc7 rbx=0000000003b80800 rcx=0000000003b80800\r\nrdx=0000000003b82080 rsi=0000000003b82080 rdi=0000000000000001\r\nrip=0000000000a7edb0 rsp=00000000069ef240 rbp=00000000008b1080\r\nr8=0000000000007628\u00a0 r9=aaaaaaaaaaaaaaab r10=00000000008b0080\r\nr11=000000000000005e r12=0000000000070fc0 r13=0000000161ffd000\r\nr14=0000000000070fc0 r15=0000000000070fcf\r\niopl=0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 nv up ei ng nz ac po cy\r\ncs=0033\u00a0 ss=002b\u00a0 ds=0000\u00a0 es=0000\u00a0 fs=0000\u00a0 gs=0000\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 efl=00000297\r\nsqlservr!BPool::MayGrow+0x3b:\r\n00000000`00a7edb0 ??\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ???\r\n0:005&gt; kc\r\n*** Stack trace for last set context - .thread\/.cxr resets it\r\nCall Site\r\nsqlservr!BPool::MayGrow\r\nsqlservr!BPool::ReplenishFreeList\r\nsqlservr!BPool::Steal\r\nsqlservr!SQLSinglePageAllocator::AllocatePages\r\nsqlservr!MemoryNode::AllocatePagesInternal\r\nsqlservr!MemoryClerkInternal::AllocatePages\r\nsqlservr!CVarPageMgr::PviNewVarPage\r\nsqlservr!CVarPageMgr::PbAllocate\r\nsqlservr!CMemObj::Alloc\r\nsqlservr!CErrorReportingManager::CwchFormatToBuffer\r\nsqlservr!CErrorReportingManager::CwchCallFormatToBuffer\r\nsqlservr!CLoginClientInfo::CLoginClientInfo\r\nsqlservr!ReportLoginFailureBySNIConn\r\nsqlservr!TDSSNIClient::AcceptCommon\r\nsqlservr!Smux::ReadDone\r\nsqlservr!SNIReadDone\r\nsqlservr!SOS_Node::ListenOnIOCompletionPort\r\nsqlservr!SOS_Task::Param::Execute\r\nsqlservr!SOS_Scheduler::RunTask\r\nsqlservr!SOS_Scheduler::ProcessTasks\r\nsqlservr!SchedulerManager::WorkerEntryPoint\r\nsqlservr!SystemThread::RunWorker\r\nsqlservr!SystemThreadDispatcher::ProcessWorker\r\nsqlservr!SchedulerManager::ThreadEntryPoint\r\nmsvcr80!endthreadex\r\nmsvcr80!endthreadex\r\nkernel32!BaseThreadInitThunk\r\nntdll!RtlUserThreadStart<\/pre>\n<p>Cette fois on la tient. Et si\u00a0 on compare les deux stacks (celle obtenue via le ThreadID 0xce8 et celle contenue dans la struct CONTEXT), on voit un d\u00e9calage:<\/p>\n<pre name=\"code\" class=\"sql\">sqlservr!BPool::MayGrow\r\nsqlservr!BPool::ReplenishFreeList<\/pre>\n<p>Et BPool:MayGrow est une indication que SQL Server demande une allocation suppl\u00e9mentaire pour ajuster Target et Committed. C&#8217;est l\u00e0 que \u00e7a coince.<\/p>\n<p>Le fichier bugcheck nous renvoie un \u00e9tat de la m\u00e9moire sur la machine au moment du probl\u00e8me:<\/p>\n<pre name=\"code\" class=\"sql\">Memory\r\nMemoryLoad = 94%\r\nTotal Physical = 4095 MB\r\nAvailable Physical = 219 MB\r\nTotal Page File = 8189 MB\r\nAvailable Page File = 2072 MB\r\nTotal Virtual = 8388607 MB\r\nAvailable Virtual = 8380979 MB\r\n**Dump thread - spid = 0, EC = 0x0000000000000000\r\n***Stack Dump being sent to K:\\MSSQL10_50.MSSQLSERVER\\MSSQL\\LOG\\SQLDump0001.txt<\/pre>\n<p>6Gb de page file utilis\u00e9, 200Mb de libre, MemoryLoad 94%. On n&#8217;est pas loin d&#8217;une OOM condition.<\/p>\n<p>Et pourquoi donc on en est arriv\u00e9 l\u00e0 s&#8217;il vous pla\u00eet ?<\/p>\n<h1>Parce que MAX SERVER MEMORY est \u00e0 sa valeur par d\u00e9faut !!<\/h1>\n<p>Vilaine habitude. Il faut toujours setter max server memory sur 64 bits.<\/p>\n<p>A+ David B.<\/p>\n<p>R\u00e9f\u00e9rences:<br \/>\n&#8211; <a href=\"http:\/\/www.microsoft.com\/technet\/prodtechnol\/sql\/2005\/diagandcorrecterrs.mspx\">How to diagnose and correct errors 17883, 17884, 17887, and 17888<\/a> &#8211; Bob Dorr Microsoft SQL Server CSS, Sameer Tejani SQL Server Development SQLOS Team.<br \/>\n&#8211; <a href=\"http:\/\/mssqlwiki.com\/2012\/08\/17\/how-to-analyze-non-yielding-scheduler-dumps\/\">How to analyze Non-Yielding scheduler or Non-yielding IOCP Listener dumps<\/a>: Karthick P.K<\/p>\n<a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F4716&#038;text=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/twitter.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F4716&#038;title=Retrouver%20la%20fonction%20%C3%A0%20l%E2%80%99origine%20d%E2%80%99un%20Non%20Yielding%20IOCP%20Listener\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/linkedin.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=Retrouver%20la%20fonction%20%C3%A0%20l%E2%80%99origine%20d%E2%80%99un%20Non%20Yielding%20IOCP%20Listener&#038;body=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20:%20https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F4716\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/mail.png\" \/><\/a>","protected":false},"excerpt":{"rendered":"<p>Petit m\u00e9mento pour retrouver la fonction \u00e0 l&#8217;origine d&#8217;un SOS non yielding ou un IOCP non yielding. On va en profiter pour rappeler les conditions de d\u00e9tection des deux ph\u00e9nom\u00e8nes. On part sur une version &gt;= 2005. Pour m\u00e9moire, cette&hellip; <a href=\"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/\" class=\"more-link\">Continuer la lecture <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":7854,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[173,5],"tags":[241,38,164,174],"class_list":["post-4716","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-operating-system","category-sqlserver","tag-debug","tag-internals","tag-sqlos","tag-win32"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Retrouver la fonction \u00e0 l&#039;origine d&#039;un Non Yielding IOCP Listener - Capdata TECH BLOG<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Retrouver la fonction \u00e0 l&#039;origine d&#039;un Non Yielding IOCP Listener - Capdata TECH BLOG\" \/>\n<meta property=\"og:description\" content=\"Petit m\u00e9mento pour retrouver la fonction \u00e0 l&#8217;origine d&#8217;un SOS non yielding ou un IOCP non yielding. On va en profiter pour rappeler les conditions de d\u00e9tection des deux ph\u00e9nom\u00e8nes. On part sur une version &gt;= 2005. Pour m\u00e9moire, cette&hellip; Continuer la lecture &rarr;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/\" \/>\n<meta property=\"og:site_name\" content=\"Capdata TECH BLOG\" \/>\n<meta property=\"article:published_time\" content=\"2013-08-12T15:56:40+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-09-13T13:00:01+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/08\/nonyieldingscheduler.png\" \/>\n\t<meta property=\"og:image:width\" content=\"676\" \/>\n\t<meta property=\"og:image:height\" content=\"455\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"David Baffaleuf\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u00c9crit par\" \/>\n\t<meta name=\"twitter:data1\" content=\"David Baffaleuf\" \/>\n\t<meta name=\"twitter:label2\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data2\" content=\"12 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/\"},\"author\":{\"name\":\"David Baffaleuf\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/person\/136297da9f61d6e4878abe0f48bc5fbf\"},\"headline\":\"Retrouver la fonction \u00e0 l&#8217;origine d&#8217;un Non Yielding IOCP Listener\",\"datePublished\":\"2013-08-12T15:56:40+00:00\",\"dateModified\":\"2019-09-13T13:00:01+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/\"},\"wordCount\":1351,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/blog.capdata.fr\/#organization\"},\"keywords\":[\"debug\",\"internals\",\"sqlos\",\"win32\"],\"articleSection\":[\"Operating System\",\"SQL Server\"],\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/\",\"url\":\"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/\",\"name\":\"Retrouver la fonction \u00e0 l'origine d'un Non Yielding IOCP Listener - Capdata TECH BLOG\",\"isPartOf\":{\"@id\":\"https:\/\/blog.capdata.fr\/#website\"},\"datePublished\":\"2013-08-12T15:56:40+00:00\",\"dateModified\":\"2019-09-13T13:00:01+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/blog.capdata.fr\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Retrouver la fonction \u00e0 l&#8217;origine d&#8217;un Non Yielding IOCP Listener\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.capdata.fr\/#website\",\"url\":\"https:\/\/blog.capdata.fr\/\",\"name\":\"Capdata TECH BLOG\",\"description\":\"Le blog technique sur les bases de donn\u00e9es de CAP DATA Consulting\",\"publisher\":{\"@id\":\"https:\/\/blog.capdata.fr\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.capdata.fr\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/blog.capdata.fr\/#organization\",\"name\":\"Capdata TECH BLOG\",\"url\":\"https:\/\/blog.capdata.fr\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp\",\"contentUrl\":\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp\",\"width\":800,\"height\":254,\"caption\":\"Capdata TECH BLOG\"},\"image\":{\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.linkedin.com\/company\/cap-data-consulting\/mycompany\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/person\/136297da9f61d6e4878abe0f48bc5fbf\",\"name\":\"David Baffaleuf\",\"sameAs\":[\"http:\/\/www.capdata.fr\"],\"url\":\"https:\/\/blog.capdata.fr\/index.php\/author\/dbaffaleuf\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Retrouver la fonction \u00e0 l'origine d'un Non Yielding IOCP Listener - Capdata TECH BLOG","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/","og_locale":"fr_FR","og_type":"article","og_title":"Retrouver la fonction \u00e0 l'origine d'un Non Yielding IOCP Listener - Capdata TECH BLOG","og_description":"Petit m\u00e9mento pour retrouver la fonction \u00e0 l&#8217;origine d&#8217;un SOS non yielding ou un IOCP non yielding. On va en profiter pour rappeler les conditions de d\u00e9tection des deux ph\u00e9nom\u00e8nes. On part sur une version &gt;= 2005. Pour m\u00e9moire, cette&hellip; Continuer la lecture &rarr;","og_url":"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/","og_site_name":"Capdata TECH BLOG","article_published_time":"2013-08-12T15:56:40+00:00","article_modified_time":"2019-09-13T13:00:01+00:00","og_image":[{"width":676,"height":455,"url":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2013\/08\/nonyieldingscheduler.png","type":"image\/png"}],"author":"David Baffaleuf","twitter_card":"summary_large_image","twitter_misc":{"\u00c9crit par":"David Baffaleuf","Dur\u00e9e de lecture estim\u00e9e":"12 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/#article","isPartOf":{"@id":"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/"},"author":{"name":"David Baffaleuf","@id":"https:\/\/blog.capdata.fr\/#\/schema\/person\/136297da9f61d6e4878abe0f48bc5fbf"},"headline":"Retrouver la fonction \u00e0 l&#8217;origine d&#8217;un Non Yielding IOCP Listener","datePublished":"2013-08-12T15:56:40+00:00","dateModified":"2019-09-13T13:00:01+00:00","mainEntityOfPage":{"@id":"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/"},"wordCount":1351,"commentCount":0,"publisher":{"@id":"https:\/\/blog.capdata.fr\/#organization"},"keywords":["debug","internals","sqlos","win32"],"articleSection":["Operating System","SQL Server"],"inLanguage":"fr-FR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/","url":"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/","name":"Retrouver la fonction \u00e0 l'origine d'un Non Yielding IOCP Listener - Capdata TECH BLOG","isPartOf":{"@id":"https:\/\/blog.capdata.fr\/#website"},"datePublished":"2013-08-12T15:56:40+00:00","dateModified":"2019-09-13T13:00:01+00:00","breadcrumb":{"@id":"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.capdata.fr\/index.php\/retrouver-la-fonction-a-lorigine-dun-iocp-non-yielding-scheduler\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/blog.capdata.fr\/"},{"@type":"ListItem","position":2,"name":"Retrouver la fonction \u00e0 l&#8217;origine d&#8217;un Non Yielding IOCP Listener"}]},{"@type":"WebSite","@id":"https:\/\/blog.capdata.fr\/#website","url":"https:\/\/blog.capdata.fr\/","name":"Capdata TECH BLOG","description":"Le blog technique sur les bases de donn\u00e9es de CAP DATA Consulting","publisher":{"@id":"https:\/\/blog.capdata.fr\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.capdata.fr\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/blog.capdata.fr\/#organization","name":"Capdata TECH BLOG","url":"https:\/\/blog.capdata.fr\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/","url":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp","contentUrl":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp","width":800,"height":254,"caption":"Capdata TECH BLOG"},"image":{"@id":"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.linkedin.com\/company\/cap-data-consulting\/mycompany\/"]},{"@type":"Person","@id":"https:\/\/blog.capdata.fr\/#\/schema\/person\/136297da9f61d6e4878abe0f48bc5fbf","name":"David Baffaleuf","sameAs":["http:\/\/www.capdata.fr"],"url":"https:\/\/blog.capdata.fr\/index.php\/author\/dbaffaleuf\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/4716","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/comments?post=4716"}],"version-history":[{"count":24,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/4716\/revisions"}],"predecessor-version":[{"id":4735,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/4716\/revisions\/4735"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/media\/7854"}],"wp:attachment":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/media?parent=4716"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/categories?post=4716"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/tags?post=4716"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}