Fx.cs 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.Runtime
  5. {
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Collections.ObjectModel;
  9. using System.Diagnostics;
  10. using System.Diagnostics.CodeAnalysis;
  11. using System.Reflection;
  12. using System.Runtime.CompilerServices;
  13. using System.Runtime.ConstrainedExecution;
  14. using System.Runtime.Diagnostics;
  15. using System.Runtime.InteropServices;
  16. using System.Runtime.Serialization;
  17. using System.Security;
  18. using System.Security.Permissions;
  19. using System.Threading;
  20. using Microsoft.Win32;
  21. static class Fx
  22. {
  23. const string defaultEventSource = "System.Runtime";
  24. #if DEBUG
  25. const string WinFXRegistryKey = @"SOFTWARE\Microsoft\NET Framework Setup\NDP";
  26. const string WcfRegistryKey = WinFXRegistryKey + @"\CDF\v4.0\Debug";
  27. const string AssertsFailFastName = "AssertsFailFast";
  28. const string BreakOnExceptionTypesName = "BreakOnExceptionTypes";
  29. const string FastDebugName = "FastDebug";
  30. const string StealthDebuggerName = "StealthDebugger";
  31. static bool breakOnExceptionTypesRetrieved;
  32. static Type[] breakOnExceptionTypesCache;
  33. static bool fastDebugRetrieved;
  34. static bool fastDebugCache;
  35. static bool stealthDebuggerRetrieved;
  36. static bool stealthDebuggerCache;
  37. #endif
  38. static ExceptionTrace exceptionTrace;
  39. static EtwDiagnosticTrace diagnosticTrace;
  40. [Fx.Tag.SecurityNote(Critical = "This delegate is called from within a ConstrainedExecutionRegion, must not be settable from PT code")]
  41. [SecurityCritical]
  42. static ExceptionHandler asynchronousThreadExceptionHandler;
  43. public static ExceptionTrace Exception
  44. {
  45. get
  46. {
  47. if (exceptionTrace == null)
  48. {
  49. // don't need a lock here since a true singleton is not required
  50. exceptionTrace = new ExceptionTrace(defaultEventSource, Trace);
  51. }
  52. return exceptionTrace;
  53. }
  54. }
  55. public static EtwDiagnosticTrace Trace
  56. {
  57. get
  58. {
  59. if (diagnosticTrace == null)
  60. {
  61. diagnosticTrace = InitializeTracing();
  62. }
  63. return diagnosticTrace;
  64. }
  65. }
  66. [Fx.Tag.SecurityNote(Critical = "Accesses SecurityCritical field EtwProvider",
  67. Safe = "Doesn't leak info\\resources")]
  68. [SecuritySafeCritical]
  69. [SuppressMessage(FxCop.Category.ReliabilityBasic, FxCop.Rule.UseNewGuidHelperRule,
  70. Justification = "This is a method that creates ETW provider passing Guid Provider ID.")]
  71. static EtwDiagnosticTrace InitializeTracing()
  72. {
  73. EtwDiagnosticTrace trace = new EtwDiagnosticTrace(defaultEventSource, EtwDiagnosticTrace.DefaultEtwProviderId);
  74. if (null != trace.EtwProvider)
  75. {
  76. trace.RefreshState += delegate()
  77. {
  78. Fx.UpdateLevel();
  79. };
  80. }
  81. Fx.UpdateLevel(trace);
  82. return trace;
  83. }
  84. public static ExceptionHandler AsynchronousThreadExceptionHandler
  85. {
  86. [Fx.Tag.SecurityNote(Critical = "access critical field", Safe = "ok for get-only access")]
  87. [SecuritySafeCritical]
  88. [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  89. get
  90. {
  91. return Fx.asynchronousThreadExceptionHandler;
  92. }
  93. [Fx.Tag.SecurityNote(Critical = "sets a critical field")]
  94. [SecurityCritical]
  95. set
  96. {
  97. Fx.asynchronousThreadExceptionHandler = value;
  98. }
  99. }
  100. // Do not call the parameter "message" or else FxCop thinks it should be localized.
  101. [Conditional("DEBUG")]
  102. public static void Assert(bool condition, string description)
  103. {
  104. if (!condition)
  105. {
  106. Assert(description);
  107. }
  108. }
  109. [Conditional("DEBUG")]
  110. public static void Assert(string description)
  111. {
  112. AssertHelper.FireAssert(description);
  113. }
  114. public static void AssertAndThrow(bool condition, string description)
  115. {
  116. if (!condition)
  117. {
  118. AssertAndThrow(description);
  119. }
  120. }
  121. [MethodImpl(MethodImplOptions.NoInlining)]
  122. public static Exception AssertAndThrow(string description)
  123. {
  124. Fx.Assert(description);
  125. TraceCore.ShipAssertExceptionMessage(Trace, description);
  126. throw new InternalException(description);
  127. }
  128. public static void AssertAndThrowFatal(bool condition, string description)
  129. {
  130. if (!condition)
  131. {
  132. AssertAndThrowFatal(description);
  133. }
  134. }
  135. [MethodImpl(MethodImplOptions.NoInlining)]
  136. public static Exception AssertAndThrowFatal(string description)
  137. {
  138. Fx.Assert(description);
  139. TraceCore.ShipAssertExceptionMessage(Trace, description);
  140. throw new FatalInternalException(description);
  141. }
  142. public static void AssertAndFailFast(bool condition, string description)
  143. {
  144. if (!condition)
  145. {
  146. AssertAndFailFast(description);
  147. }
  148. }
  149. // This never returns. The Exception return type lets you write 'throw AssertAndFailFast()' which tells the compiler/tools that
  150. // execution stops.
  151. [Fx.Tag.SecurityNote(Critical = "Calls into critical method Environment.FailFast",
  152. Safe = "The side affect of the app crashing is actually intended here")]
  153. [SecuritySafeCritical]
  154. [MethodImpl(MethodImplOptions.NoInlining)]
  155. public static Exception AssertAndFailFast(string description)
  156. {
  157. Fx.Assert(description);
  158. string failFastMessage = InternalSR.FailFastMessage(description);
  159. // The catch is here to force the finally to run, as finallys don't run until the stack walk gets to a catch.
  160. // The catch makes sure that the finally will run before the stack-walk leaves the frame, but the code inside is impossible to reach.
  161. try
  162. {
  163. try
  164. {
  165. Fx.Exception.TraceFailFast(failFastMessage);
  166. }
  167. finally
  168. {
  169. Environment.FailFast(failFastMessage);
  170. }
  171. }
  172. catch
  173. {
  174. throw;
  175. }
  176. return null; // we'll never get here since we've just fail-fasted
  177. }
  178. public static bool IsFatal(Exception exception)
  179. {
  180. while (exception != null)
  181. {
  182. if (exception is FatalException ||
  183. (exception is OutOfMemoryException && !(exception is InsufficientMemoryException)) ||
  184. exception is ThreadAbortException ||
  185. exception is FatalInternalException)
  186. {
  187. return true;
  188. }
  189. // These exceptions aren't themselves fatal, but since the CLR uses them to wrap other exceptions,
  190. // we want to check to see whether they've been used to wrap a fatal exception. If so, then they
  191. // count as fatal.
  192. if (exception is TypeInitializationException ||
  193. exception is TargetInvocationException)
  194. {
  195. exception = exception.InnerException;
  196. }
  197. else if (exception is AggregateException)
  198. {
  199. // AggregateExceptions have a collection of inner exceptions, which may themselves be other
  200. // wrapping exceptions (including nested AggregateExceptions). Recursively walk this
  201. // hierarchy. The (singular) InnerException is included in the collection.
  202. ReadOnlyCollection<Exception> innerExceptions = ((AggregateException)exception).InnerExceptions;
  203. foreach (Exception innerException in innerExceptions)
  204. {
  205. if (IsFatal(innerException))
  206. {
  207. return true;
  208. }
  209. }
  210. break;
  211. }
  212. else
  213. {
  214. break;
  215. }
  216. }
  217. return false;
  218. }
  219. // This method should be only used for debug build.
  220. internal static bool AssertsFailFast
  221. {
  222. get
  223. {
  224. #if DEBUG
  225. object value;
  226. return TryGetDebugSwitch(Fx.AssertsFailFastName, out value) &&
  227. typeof(int).IsAssignableFrom(value.GetType()) && ((int)value) != 0;
  228. #else
  229. return false;
  230. #endif
  231. }
  232. }
  233. // This property should be only used for debug build.
  234. internal static Type[] BreakOnExceptionTypes
  235. {
  236. get
  237. {
  238. #if DEBUG
  239. if (!Fx.breakOnExceptionTypesRetrieved)
  240. {
  241. object value;
  242. if (TryGetDebugSwitch(Fx.BreakOnExceptionTypesName, out value))
  243. {
  244. string[] typeNames = value as string[];
  245. if (typeNames != null && typeNames.Length > 0)
  246. {
  247. List<Type> types = new List<Type>(typeNames.Length);
  248. for (int i = 0; i < typeNames.Length; i++)
  249. {
  250. types.Add(Type.GetType(typeNames[i], false));
  251. }
  252. if (types.Count != 0)
  253. {
  254. Fx.breakOnExceptionTypesCache = types.ToArray();
  255. }
  256. }
  257. }
  258. Fx.breakOnExceptionTypesRetrieved = true;
  259. }
  260. return Fx.breakOnExceptionTypesCache;
  261. #else
  262. return null;
  263. #endif
  264. }
  265. }
  266. // This property should be only used for debug build.
  267. internal static bool FastDebug
  268. {
  269. get
  270. {
  271. #if DEBUG
  272. if (!Fx.fastDebugRetrieved)
  273. {
  274. object value;
  275. if (TryGetDebugSwitch(Fx.FastDebugName, out value))
  276. {
  277. Fx.fastDebugCache = typeof(int).IsAssignableFrom(value.GetType()) && ((int)value) != 0;
  278. }
  279. Fx.fastDebugRetrieved = true;
  280. }
  281. return Fx.fastDebugCache;
  282. #else
  283. return false;
  284. #endif
  285. }
  286. }
  287. // This property should be only used for debug build.
  288. internal static bool StealthDebugger
  289. {
  290. get
  291. {
  292. #if DEBUG
  293. if (!Fx.stealthDebuggerRetrieved)
  294. {
  295. object value;
  296. if (TryGetDebugSwitch(Fx.StealthDebuggerName, out value))
  297. {
  298. Fx.stealthDebuggerCache = typeof(int).IsAssignableFrom(value.GetType()) && ((int)value) != 0;
  299. }
  300. Fx.stealthDebuggerRetrieved = true;
  301. }
  302. return Fx.stealthDebuggerCache;
  303. #else
  304. return false;
  305. #endif
  306. }
  307. }
  308. #if DEBUG
  309. static bool TryGetDebugSwitch(string name, out object value)
  310. {
  311. value = null;
  312. try
  313. {
  314. RegistryKey key = Registry.LocalMachine.OpenSubKey(Fx.WcfRegistryKey);
  315. if (key != null)
  316. {
  317. using (key)
  318. {
  319. value = key.GetValue(name);
  320. }
  321. }
  322. }
  323. catch (SecurityException)
  324. {
  325. // This debug-only code shouldn't trace.
  326. }
  327. return value != null;
  328. }
  329. #endif
  330. public static Action<T1> ThunkCallback<T1>(Action<T1> callback)
  331. {
  332. return (new ActionThunk<T1>(callback)).ThunkFrame;
  333. }
  334. public static AsyncCallback ThunkCallback(AsyncCallback callback)
  335. {
  336. return (new AsyncThunk(callback)).ThunkFrame;
  337. }
  338. public static WaitCallback ThunkCallback(WaitCallback callback)
  339. {
  340. return (new WaitThunk(callback)).ThunkFrame;
  341. }
  342. public static TimerCallback ThunkCallback(TimerCallback callback)
  343. {
  344. return (new TimerThunk(callback)).ThunkFrame;
  345. }
  346. public static WaitOrTimerCallback ThunkCallback(WaitOrTimerCallback callback)
  347. {
  348. return (new WaitOrTimerThunk(callback)).ThunkFrame;
  349. }
  350. public static SendOrPostCallback ThunkCallback(SendOrPostCallback callback)
  351. {
  352. return (new SendOrPostThunk(callback)).ThunkFrame;
  353. }
  354. [Fx.Tag.SecurityNote(Critical = "Construct the unsafe object IOCompletionThunk")]
  355. [SecurityCritical]
  356. public static IOCompletionCallback ThunkCallback(IOCompletionCallback callback)
  357. {
  358. return (new IOCompletionThunk(callback)).ThunkFrame;
  359. }
  360. [SuppressMessage(FxCop.Category.ReliabilityBasic, FxCop.Rule.UseNewGuidHelperRule,
  361. Justification = "These are the core methods that should be used for all other Guid(string) calls.")]
  362. public static Guid CreateGuid(string guidString)
  363. {
  364. bool success = false;
  365. Guid result = Guid.Empty;
  366. try
  367. {
  368. result = new Guid(guidString);
  369. success = true;
  370. }
  371. finally
  372. {
  373. if (!success)
  374. {
  375. AssertAndThrow("Creation of the Guid failed.");
  376. }
  377. }
  378. return result;
  379. }
  380. [SuppressMessage(FxCop.Category.ReliabilityBasic, FxCop.Rule.UseNewGuidHelperRule,
  381. Justification = "These are the core methods that should be used for all other Guid(string) calls.")]
  382. public static bool TryCreateGuid(string guidString, out Guid result)
  383. {
  384. bool success = false;
  385. result = Guid.Empty;
  386. try
  387. {
  388. result = new Guid(guidString);
  389. success = true;
  390. }
  391. catch (ArgumentException)
  392. {
  393. // ---- this
  394. }
  395. catch (FormatException)
  396. {
  397. // ---- this
  398. }
  399. catch (OverflowException)
  400. {
  401. // ---- this
  402. }
  403. return success;
  404. }
  405. public static byte[] AllocateByteArray(int size)
  406. {
  407. try
  408. {
  409. // Safe to catch OOM from this as long as the ONLY thing it does is a simple allocation of a primitive type (no method calls).
  410. return new byte[size];
  411. }
  412. catch (OutOfMemoryException exception)
  413. {
  414. // Convert OOM into an exception that can be safely handled by higher layers.
  415. throw Fx.Exception.AsError(
  416. new InsufficientMemoryException(InternalSR.BufferAllocationFailed(size), exception));
  417. }
  418. }
  419. public static char[] AllocateCharArray(int size)
  420. {
  421. try
  422. {
  423. // Safe to catch OOM from this as long as the ONLY thing it does is a simple allocation of a primitive type (no method calls).
  424. return new char[size];
  425. }
  426. catch (OutOfMemoryException exception)
  427. {
  428. // Convert OOM into an exception that can be safely handled by higher layers.
  429. throw Fx.Exception.AsError(
  430. new InsufficientMemoryException(InternalSR.BufferAllocationFailed(size * sizeof(char)), exception));
  431. }
  432. }
  433. [SuppressMessage(FxCop.Category.Design, FxCop.Rule.DoNotCatchGeneralExceptionTypes,
  434. Justification = "Don't want to hide the exception which is about to crash the process.")]
  435. [Fx.Tag.SecurityNote(Miscellaneous = "Must not call into PT code as it is called within a CER.")]
  436. [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  437. static void TraceExceptionNoThrow(Exception exception)
  438. {
  439. try
  440. {
  441. // This call exits the CER. However, when still inside a catch, normal ThreadAbort is prevented.
  442. // Rude ThreadAbort will still be allowed to terminate processing.
  443. Fx.Exception.TraceUnhandledException(exception);
  444. }
  445. catch
  446. {
  447. // This empty catch is only acceptable because we are a) in a CER and b) processing an exception
  448. // which is about to crash the process anyway.
  449. }
  450. }
  451. [SuppressMessage(FxCop.Category.Design, FxCop.Rule.DoNotCatchGeneralExceptionTypes,
  452. Justification = "Don't want to hide the exception which is about to crash the process.")]
  453. [SuppressMessage(FxCop.Category.ReliabilityBasic, FxCop.Rule.IsFatalRule,
  454. Justification = "Don't want to hide the exception which is about to crash the process.")]
  455. [Fx.Tag.SecurityNote(Miscellaneous = "Must not call into PT code as it is called within a CER.")]
  456. [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
  457. static bool HandleAtThreadBase(Exception exception)
  458. {
  459. // This area is too sensitive to do anything but return.
  460. if (exception == null)
  461. {
  462. Fx.Assert("Null exception in HandleAtThreadBase.");
  463. return false;
  464. }
  465. TraceExceptionNoThrow(exception);
  466. try
  467. {
  468. ExceptionHandler handler = Fx.AsynchronousThreadExceptionHandler;
  469. return handler == null ? false : handler.HandleException(exception);
  470. }
  471. catch (Exception secondException)
  472. {
  473. // Don't let a new exception hide the original exception.
  474. TraceExceptionNoThrow(secondException);
  475. }
  476. return false;
  477. }
  478. static void UpdateLevel(EtwDiagnosticTrace trace)
  479. {
  480. if (trace == null)
  481. {
  482. return;
  483. }
  484. if (TraceCore.ActionItemCallbackInvokedIsEnabled(trace) ||
  485. TraceCore.ActionItemScheduledIsEnabled(trace))
  486. {
  487. trace.SetEnd2EndActivityTracingEnabled(true);
  488. }
  489. }
  490. static void UpdateLevel()
  491. {
  492. UpdateLevel(Fx.Trace);
  493. }
  494. public abstract class ExceptionHandler
  495. {
  496. [Fx.Tag.SecurityNote(Miscellaneous = "Must not call into PT code as it is called within a CER.")]
  497. public abstract bool HandleException(Exception exception);
  498. }
  499. public static class Tag
  500. {
  501. public enum CacheAttrition
  502. {
  503. None,
  504. ElementOnTimer,
  505. // A finalizer/WeakReference based cache, where the elements are held by WeakReferences (or hold an
  506. // inner object by a WeakReference), and the weakly-referenced object has a finalizer which cleans the
  507. // item from the cache.
  508. ElementOnGC,
  509. // A cache that provides a per-element token, delegate, interface, or other piece of context that can
  510. // be used to remove the element (such as IDisposable).
  511. ElementOnCallback,
  512. FullPurgeOnTimer,
  513. FullPurgeOnEachAccess,
  514. PartialPurgeOnTimer,
  515. PartialPurgeOnEachAccess,
  516. }
  517. public enum ThrottleAction
  518. {
  519. Reject,
  520. Pause,
  521. }
  522. public enum ThrottleMetric
  523. {
  524. Count,
  525. Rate,
  526. Other,
  527. }
  528. public enum Location
  529. {
  530. InProcess,
  531. OutOfProcess,
  532. LocalSystem,
  533. LocalOrRemoteSystem, // as in a file that might live on a share
  534. RemoteSystem,
  535. }
  536. public enum SynchronizationKind
  537. {
  538. LockStatement,
  539. MonitorWait,
  540. MonitorExplicit,
  541. InterlockedNoSpin,
  542. InterlockedWithSpin,
  543. // Same as LockStatement if the field type is object.
  544. FromFieldType,
  545. }
  546. [Flags]
  547. public enum BlocksUsing
  548. {
  549. MonitorEnter,
  550. MonitorWait,
  551. ManualResetEvent,
  552. AutoResetEvent,
  553. AsyncResult,
  554. IAsyncResult,
  555. PInvoke,
  556. InputQueue,
  557. ThreadNeutralSemaphore,
  558. PrivatePrimitive,
  559. OtherInternalPrimitive,
  560. OtherFrameworkPrimitive,
  561. OtherInterop,
  562. Other,
  563. NonBlocking, // For use by non-blocking SynchronizationPrimitives such as IOThreadScheduler
  564. }
  565. public static class Strings
  566. {
  567. internal const string ExternallyManaged = "externally managed";
  568. internal const string AppDomain = "AppDomain";
  569. internal const string DeclaringInstance = "instance of declaring class";
  570. internal const string Unbounded = "unbounded";
  571. internal const string Infinite = "infinite";
  572. }
  573. [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Property | AttributeTargets.Class,
  574. AllowMultiple = true, Inherited = false)]
  575. [Conditional("DEBUG")]
  576. public sealed class FriendAccessAllowedAttribute : Attribute
  577. {
  578. public FriendAccessAllowedAttribute(string assemblyName) :
  579. base()
  580. {
  581. this.AssemblyName = assemblyName;
  582. }
  583. public string AssemblyName { get; set; }
  584. }
  585. public static class Throws
  586. {
  587. [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor,
  588. AllowMultiple = true, Inherited = false)]
  589. [Conditional("CODE_ANALYSIS_CDF")]
  590. public sealed class TimeoutAttribute : ThrowsAttribute
  591. {
  592. public TimeoutAttribute() :
  593. this("The operation timed out.")
  594. {
  595. }
  596. public TimeoutAttribute(string diagnosis) :
  597. base(typeof(TimeoutException), diagnosis)
  598. {
  599. }
  600. }
  601. }
  602. [AttributeUsage(AttributeTargets.Field)]
  603. [Conditional("CODE_ANALYSIS_CDF")]
  604. public sealed class CacheAttribute : Attribute
  605. {
  606. readonly Type elementType;
  607. readonly CacheAttrition cacheAttrition;
  608. public CacheAttribute(Type elementType, CacheAttrition cacheAttrition)
  609. {
  610. Scope = Strings.DeclaringInstance;
  611. SizeLimit = Strings.Unbounded;
  612. Timeout = Strings.Infinite;
  613. if (elementType == null)
  614. {
  615. throw Fx.Exception.ArgumentNull("elementType");
  616. }
  617. this.elementType = elementType;
  618. this.cacheAttrition = cacheAttrition;
  619. }
  620. public Type ElementType
  621. {
  622. get
  623. {
  624. return this.elementType;
  625. }
  626. }
  627. public CacheAttrition CacheAttrition
  628. {
  629. get
  630. {
  631. return this.cacheAttrition;
  632. }
  633. }
  634. public string Scope { get; set; }
  635. public string SizeLimit { get; set; }
  636. public string Timeout { get; set; }
  637. }
  638. [AttributeUsage(AttributeTargets.Field)]
  639. [Conditional("CODE_ANALYSIS_CDF")]
  640. public sealed class QueueAttribute : Attribute
  641. {
  642. readonly Type elementType;
  643. public QueueAttribute(Type elementType)
  644. {
  645. Scope = Strings.DeclaringInstance;
  646. SizeLimit = Strings.Unbounded;
  647. if (elementType == null)
  648. {
  649. throw Fx.Exception.ArgumentNull("elementType");
  650. }
  651. this.elementType = elementType;
  652. }
  653. public Type ElementType
  654. {
  655. get
  656. {
  657. return this.elementType;
  658. }
  659. }
  660. public string Scope { get; set; }
  661. public string SizeLimit { get; set; }
  662. public bool StaleElementsRemovedImmediately { get; set; }
  663. public bool EnqueueThrowsIfFull { get; set; }
  664. }
  665. [AttributeUsage(AttributeTargets.Field)]
  666. [Conditional("CODE_ANALYSIS_CDF")]
  667. public sealed class ThrottleAttribute : Attribute
  668. {
  669. readonly ThrottleAction throttleAction;
  670. readonly ThrottleMetric throttleMetric;
  671. readonly string limit;
  672. public ThrottleAttribute(ThrottleAction throttleAction, ThrottleMetric throttleMetric, string limit)
  673. {
  674. Scope = Strings.AppDomain;
  675. if (string.IsNullOrEmpty(limit))
  676. {
  677. throw Fx.Exception.ArgumentNullOrEmpty("limit");
  678. }
  679. this.throttleAction = throttleAction;
  680. this.throttleMetric = throttleMetric;
  681. this.limit = limit;
  682. }
  683. public ThrottleAction ThrottleAction
  684. {
  685. get
  686. {
  687. return this.throttleAction;
  688. }
  689. }
  690. public ThrottleMetric ThrottleMetric
  691. {
  692. get
  693. {
  694. return this.throttleMetric;
  695. }
  696. }
  697. public string Limit
  698. {
  699. get
  700. {
  701. return this.limit;
  702. }
  703. }
  704. public string Scope
  705. {
  706. get; set;
  707. }
  708. }
  709. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Method | AttributeTargets.Constructor,
  710. AllowMultiple = true, Inherited = false)]
  711. [Conditional("CODE_ANALYSIS_CDF")]
  712. public sealed class ExternalResourceAttribute : Attribute
  713. {
  714. readonly Location location;
  715. readonly string description;
  716. public ExternalResourceAttribute(Location location, string description)
  717. {
  718. this.location = location;
  719. this.description = description;
  720. }
  721. public Location Location
  722. {
  723. get
  724. {
  725. return this.location;
  726. }
  727. }
  728. public string Description
  729. {
  730. get
  731. {
  732. return this.description;
  733. }
  734. }
  735. }
  736. // Set on a class when that class uses lock (this) - acts as though it were on a field
  737. // private object this;
  738. [AttributeUsage(AttributeTargets.Field | AttributeTargets.Class, Inherited = false)]
  739. [Conditional("CODE_ANALYSIS_CDF")]
  740. public sealed class SynchronizationObjectAttribute : Attribute
  741. {
  742. public SynchronizationObjectAttribute()
  743. {
  744. Blocking = true;
  745. Scope = Strings.DeclaringInstance;
  746. Kind = SynchronizationKind.FromFieldType;
  747. }
  748. public bool Blocking { get; set; }
  749. public string Scope { get; set; }
  750. public SynchronizationKind Kind { get; set; }
  751. }
  752. [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct, Inherited = true)]
  753. [Conditional("CODE_ANALYSIS_CDF")]
  754. public sealed class SynchronizationPrimitiveAttribute : Attribute
  755. {
  756. readonly BlocksUsing blocksUsing;
  757. public SynchronizationPrimitiveAttribute(BlocksUsing blocksUsing)
  758. {
  759. this.blocksUsing = blocksUsing;
  760. }
  761. public BlocksUsing BlocksUsing
  762. {
  763. get
  764. {
  765. return this.blocksUsing;
  766. }
  767. }
  768. public bool SupportsAsync { get; set; }
  769. public bool Spins { get; set; }
  770. public string ReleaseMethod { get; set; }
  771. }
  772. [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false)]
  773. [Conditional("CODE_ANALYSIS_CDF")]
  774. public sealed class BlockingAttribute : Attribute
  775. {
  776. public BlockingAttribute()
  777. {
  778. }
  779. public string CancelMethod { get; set; }
  780. public Type CancelDeclaringType { get; set; }
  781. public string Conditional { get; set; }
  782. }
  783. // Sometime a method will call a conditionally-blocking method in such a way that it is guaranteed
  784. // not to block (i.e. the condition can be Asserted false). Such a method can be marked as
  785. // GuaranteeNonBlocking as an assertion that the method doesn't block despite calling a blocking method.
  786. //
  787. // Methods that don't call blocking methods and aren't marked as Blocking are assumed not to block, so
  788. // they do not require this attribute.
  789. [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false)]
  790. [Conditional("CODE_ANALYSIS_CDF")]
  791. public sealed class GuaranteeNonBlockingAttribute : Attribute
  792. {
  793. public GuaranteeNonBlockingAttribute()
  794. {
  795. }
  796. }
  797. [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false)]
  798. [Conditional("CODE_ANALYSIS_CDF")]
  799. public sealed class NonThrowingAttribute : Attribute
  800. {
  801. public NonThrowingAttribute()
  802. {
  803. }
  804. }
  805. [SuppressMessage(FxCop.Category.Performance, "CA1813:AvoidUnsealedAttributes",
  806. Justification = "This is intended to be an attribute heirarchy. It does not affect product perf.")]
  807. [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor,
  808. AllowMultiple = true, Inherited = false)]
  809. [Conditional("CODE_ANALYSIS_CDF")]
  810. public class ThrowsAttribute : Attribute
  811. {
  812. readonly Type exceptionType;
  813. readonly string diagnosis;
  814. public ThrowsAttribute(Type exceptionType, string diagnosis)
  815. {
  816. if (exceptionType == null)
  817. {
  818. throw Fx.Exception.ArgumentNull("exceptionType");
  819. }
  820. if (string.IsNullOrEmpty(diagnosis))
  821. {
  822. throw Fx.Exception.ArgumentNullOrEmpty("diagnosis");
  823. }
  824. this.exceptionType = exceptionType;
  825. this.diagnosis = diagnosis;
  826. }
  827. public Type ExceptionType
  828. {
  829. get
  830. {
  831. return this.exceptionType;
  832. }
  833. }
  834. public string Diagnosis
  835. {
  836. get
  837. {
  838. return this.diagnosis;
  839. }
  840. }
  841. }
  842. [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor, Inherited = false)]
  843. [Conditional("CODE_ANALYSIS_CDF")]
  844. public sealed class InheritThrowsAttribute : Attribute
  845. {
  846. public InheritThrowsAttribute()
  847. {
  848. }
  849. public Type FromDeclaringType { get; set; }
  850. public string From { get; set; }
  851. }
  852. [AttributeUsage(AttributeTargets.Property, AllowMultiple = false, Inherited = true)]
  853. [Conditional("CODE_ANALYSIS_CDF")]
  854. public sealed class KnownXamlExternalAttribute : Attribute
  855. {
  856. public KnownXamlExternalAttribute()
  857. {
  858. }
  859. }
  860. [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct, AllowMultiple = false, Inherited = false)]
  861. [Conditional("CODE_ANALYSIS_CDF")]
  862. public sealed class XamlVisibleAttribute : Attribute
  863. {
  864. public XamlVisibleAttribute()
  865. : this(true)
  866. {
  867. }
  868. public XamlVisibleAttribute(bool visible)
  869. {
  870. this.Visible = visible;
  871. }
  872. public bool Visible
  873. {
  874. get;
  875. private set;
  876. }
  877. }
  878. [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Module | AttributeTargets.Class |
  879. AttributeTargets.Struct | AttributeTargets.Enum | AttributeTargets.Constructor | AttributeTargets.Method |
  880. AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Interface |
  881. AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)]
  882. [Conditional("CODE_ANALYSIS_CDF")]
  883. public sealed class SecurityNoteAttribute : Attribute
  884. {
  885. public SecurityNoteAttribute()
  886. {
  887. }
  888. public string Critical
  889. {
  890. get;
  891. set;
  892. }
  893. public string Safe
  894. {
  895. get;
  896. set;
  897. }
  898. public string Miscellaneous
  899. {
  900. get;
  901. set;
  902. }
  903. }
  904. }
  905. abstract class Thunk<T> where T : class
  906. {
  907. [Fx.Tag.SecurityNote(Critical = "Make these safe to use in SecurityCritical contexts.")]
  908. [SecurityCritical]
  909. T callback;
  910. [Fx.Tag.SecurityNote(Critical = "Accesses critical field.", Safe = "Data provided by caller.")]
  911. [SecuritySafeCritical]
  912. protected Thunk(T callback)
  913. {
  914. this.callback = callback;
  915. }
  916. internal T Callback
  917. {
  918. [Fx.Tag.SecurityNote(Critical = "Accesses critical field.", Safe = "Data is not privileged.")]
  919. [SecuritySafeCritical]
  920. get
  921. {
  922. return this.callback;
  923. }
  924. }
  925. }
  926. sealed class ActionThunk<T1> : Thunk<Action<T1>>
  927. {
  928. public ActionThunk(Action<T1> callback) : base(callback)
  929. {
  930. }
  931. public Action<T1> ThunkFrame
  932. {
  933. get
  934. {
  935. return new Action<T1>(UnhandledExceptionFrame);
  936. }
  937. }
  938. [Fx.Tag.SecurityNote(Critical = "Calls PrepareConstrainedRegions which has a LinkDemand",
  939. Safe = "Guaranteed not to call into PT user code from the finally.")]
  940. [SecuritySafeCritical]
  941. void UnhandledExceptionFrame(T1 result)
  942. {
  943. RuntimeHelpers.PrepareConstrainedRegions();
  944. try
  945. {
  946. Callback(result);
  947. }
  948. catch (Exception exception)
  949. {
  950. if (!Fx.HandleAtThreadBase(exception))
  951. {
  952. throw;
  953. }
  954. }
  955. }
  956. }
  957. sealed class AsyncThunk : Thunk<AsyncCallback>
  958. {
  959. public AsyncThunk(AsyncCallback callback) : base(callback)
  960. {
  961. }
  962. public AsyncCallback ThunkFrame
  963. {
  964. get
  965. {
  966. return new AsyncCallback(UnhandledExceptionFrame);
  967. }
  968. }
  969. [Fx.Tag.SecurityNote(Critical = "Calls PrepareConstrainedRegions which has a LinkDemand",
  970. Safe = "Guaranteed not to call into PT user code from the finally.")]
  971. [SecuritySafeCritical]
  972. void UnhandledExceptionFrame(IAsyncResult result)
  973. {
  974. RuntimeHelpers.PrepareConstrainedRegions();
  975. try
  976. {
  977. Callback(result);
  978. }
  979. catch (Exception exception)
  980. {
  981. if (!Fx.HandleAtThreadBase(exception))
  982. {
  983. throw;
  984. }
  985. }
  986. }
  987. }
  988. sealed class WaitThunk : Thunk<WaitCallback>
  989. {
  990. public WaitThunk(WaitCallback callback) : base(callback)
  991. {
  992. }
  993. public WaitCallback ThunkFrame
  994. {
  995. get
  996. {
  997. return new WaitCallback(UnhandledExceptionFrame);
  998. }
  999. }
  1000. [Fx.Tag.SecurityNote(Critical = "Calls PrepareConstrainedRegions which has a LinkDemand",
  1001. Safe = "Guaranteed not to call into PT user code from the finally.")]
  1002. [SecuritySafeCritical]
  1003. void UnhandledExceptionFrame(object state)
  1004. {
  1005. RuntimeHelpers.PrepareConstrainedRegions();
  1006. try
  1007. {
  1008. Callback(state);
  1009. }
  1010. catch (Exception exception)
  1011. {
  1012. if (!Fx.HandleAtThreadBase(exception))
  1013. {
  1014. throw;
  1015. }
  1016. }
  1017. }
  1018. }
  1019. sealed class TimerThunk : Thunk<TimerCallback>
  1020. {
  1021. public TimerThunk(TimerCallback callback) : base(callback)
  1022. {
  1023. }
  1024. public TimerCallback ThunkFrame
  1025. {
  1026. get
  1027. {
  1028. return new TimerCallback(UnhandledExceptionFrame);
  1029. }
  1030. }
  1031. [Fx.Tag.SecurityNote(Critical = "Calls PrepareConstrainedRegions which has a LinkDemand",
  1032. Safe = "Guaranteed not to call into PT user code from the finally.")]
  1033. [SecuritySafeCritical]
  1034. void UnhandledExceptionFrame(object state)
  1035. {
  1036. RuntimeHelpers.PrepareConstrainedRegions();
  1037. try
  1038. {
  1039. Callback(state);
  1040. }
  1041. catch (Exception exception)
  1042. {
  1043. if (!Fx.HandleAtThreadBase(exception))
  1044. {
  1045. throw;
  1046. }
  1047. }
  1048. }
  1049. }
  1050. sealed class WaitOrTimerThunk : Thunk<WaitOrTimerCallback>
  1051. {
  1052. public WaitOrTimerThunk(WaitOrTimerCallback callback) : base(callback)
  1053. {
  1054. }
  1055. public WaitOrTimerCallback ThunkFrame
  1056. {
  1057. get
  1058. {
  1059. return new WaitOrTimerCallback(UnhandledExceptionFrame);
  1060. }
  1061. }
  1062. [Fx.Tag.SecurityNote(Critical = "Calls PrepareConstrainedRegions which has a LinkDemand",
  1063. Safe = "Guaranteed not to call into PT user code from the finally.")]
  1064. [SecuritySafeCritical]
  1065. void UnhandledExceptionFrame(object state, bool timedOut)
  1066. {
  1067. RuntimeHelpers.PrepareConstrainedRegions();
  1068. try
  1069. {
  1070. Callback(state, timedOut);
  1071. }
  1072. catch (Exception exception)
  1073. {
  1074. if (!Fx.HandleAtThreadBase(exception))
  1075. {
  1076. throw;
  1077. }
  1078. }
  1079. }
  1080. }
  1081. sealed class SendOrPostThunk : Thunk<SendOrPostCallback>
  1082. {
  1083. public SendOrPostThunk(SendOrPostCallback callback) : base(callback)
  1084. {
  1085. }
  1086. public SendOrPostCallback ThunkFrame
  1087. {
  1088. get
  1089. {
  1090. return new SendOrPostCallback(UnhandledExceptionFrame);
  1091. }
  1092. }
  1093. [Fx.Tag.SecurityNote(Critical = "Calls PrepareConstrainedRegions which has a LinkDemand",
  1094. Safe = "Guaranteed not to call into PT user code from the finally.")]
  1095. [SecuritySafeCritical]
  1096. void UnhandledExceptionFrame(object state)
  1097. {
  1098. RuntimeHelpers.PrepareConstrainedRegions();
  1099. try
  1100. {
  1101. Callback(state);
  1102. }
  1103. catch (Exception exception)
  1104. {
  1105. if (!Fx.HandleAtThreadBase(exception))
  1106. {
  1107. throw;
  1108. }
  1109. }
  1110. }
  1111. }
  1112. // This can't derive from Thunk since T would be unsafe.
  1113. [Fx.Tag.SecurityNote(Critical = "unsafe object")]
  1114. [SecurityCritical]
  1115. unsafe sealed class IOCompletionThunk
  1116. {
  1117. [Fx.Tag.SecurityNote(Critical = "Make these safe to use in SecurityCritical contexts.")]
  1118. IOCompletionCallback callback;
  1119. [Fx.Tag.SecurityNote(Critical = "Accesses critical field.", Safe = "Data provided by caller.")]
  1120. public IOCompletionThunk(IOCompletionCallback callback)
  1121. {
  1122. this.callback = callback;
  1123. }
  1124. public IOCompletionCallback ThunkFrame
  1125. {
  1126. [Fx.Tag.SecurityNote(Safe = "returns a delegate around the safe method UnhandledExceptionFrame")]
  1127. get
  1128. {
  1129. return new IOCompletionCallback(UnhandledExceptionFrame);
  1130. }
  1131. }
  1132. [Fx.Tag.SecurityNote(Critical = "Accesses critical field, calls PrepareConstrainedRegions which has a LinkDemand",
  1133. Safe = "Delegates can be invoked, guaranteed not to call into PT user code from the finally.")]
  1134. void UnhandledExceptionFrame(uint error, uint bytesRead, NativeOverlapped* nativeOverlapped)
  1135. {
  1136. RuntimeHelpers.PrepareConstrainedRegions();
  1137. try
  1138. {
  1139. this.callback(error, bytesRead, nativeOverlapped);
  1140. }
  1141. catch (Exception exception)
  1142. {
  1143. if (!Fx.HandleAtThreadBase(exception))
  1144. {
  1145. throw;
  1146. }
  1147. }
  1148. }
  1149. }
  1150. [Serializable]
  1151. class InternalException : SystemException
  1152. {
  1153. public InternalException(string description)
  1154. : base(InternalSR.ShipAssertExceptionMessage(description))
  1155. {
  1156. }
  1157. protected InternalException(SerializationInfo info, StreamingContext context)
  1158. : base(info, context)
  1159. {
  1160. }
  1161. }
  1162. [Serializable]
  1163. class FatalInternalException : InternalException
  1164. {
  1165. public FatalInternalException(string description)
  1166. : base(description)
  1167. {
  1168. }
  1169. protected FatalInternalException(SerializationInfo info, StreamingContext context)
  1170. : base(info, context)
  1171. {
  1172. }
  1173. }
  1174. }
  1175. }