Skip to content

Commit b938ea2

Browse files
author
Davoud Eshtehari
committed
fix
1 parent 94f4019 commit b938ea2

File tree

4 files changed

+107
-14
lines changed

4 files changed

+107
-14
lines changed

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SNI/SNIStreams.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ public override async Task<int> ReadAsync(byte[] buffer, int offset, int count,
3333
{
3434
return await base.ReadAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
3535
}
36+
catch (System.Exception e)
37+
{
38+
SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNISslStream), EventType.ERR, "Internal Exception occurred while reading data: {0}", args0: e?.Message);
39+
throw;
40+
}
3641
finally
3742
{
3843
_readAsyncSemaphore.Release();
@@ -47,6 +52,11 @@ public override async Task WriteAsync(byte[] buffer, int offset, int count, Canc
4752
{
4853
await base.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
4954
}
55+
catch (System.Exception e)
56+
{
57+
SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNISslStream), EventType.ERR, "Internal Exception occurred while writing data: {0}", args0: e?.Message);
58+
throw;
59+
}
5060
finally
5161
{
5262
_writeAsyncSemaphore.Release();
@@ -76,6 +86,11 @@ public override async Task<int> ReadAsync(byte[] buffer, int offset, int count,
7686
{
7787
return await base.ReadAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
7888
}
89+
catch (System.Exception e)
90+
{
91+
SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNINetworkStream), EventType.ERR, "Internal Exception occurred while reading data: {0}", args0: e?.Message);
92+
throw;
93+
}
7994
finally
8095
{
8196
_readAsyncSemaphore.Release();
@@ -90,6 +105,11 @@ public override async Task WriteAsync(byte[] buffer, int offset, int count, Canc
90105
{
91106
await base.WriteAsync(buffer, offset, count, cancellationToken).ConfigureAwait(false);
92107
}
108+
catch (System.Exception e)
109+
{
110+
SqlClientEventSource.Log.TrySNITraceEvent(nameof(SNINetworkStream), EventType.ERR, "Internal Exception occurred while writing data: {0}", args0: e?.Message);
111+
throw;
112+
}
93113
finally
94114
{
95115
_writeAsyncSemaphore.Release();

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/SqlCommand.cs

Lines changed: 63 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,9 @@ internal bool IsActiveConnectionValid(SqlConnection activeConnection)
253253

254254
internal void ResetAsyncState()
255255
{
256+
SqlClientEventSource.Log.TryTraceEvent("CachedAsyncState.ResetAsyncState | API | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}",
257+
_cachedAsyncConnection?.ObjectID, _cachedAsyncConnection?.ClientConnectionId,
258+
_cachedAsyncConnection?.Parser?.MARSOn, _cachedAsyncConnection?.AsyncCommandInProgress);
256259
_cachedAsyncCloseCount = -1;
257260
_cachedAsyncResult = null;
258261
if (_cachedAsyncConnection != null)
@@ -270,6 +273,7 @@ internal void SetActiveConnectionAndResult(TaskCompletionSource<object> completi
270273
{
271274
Debug.Assert(activeConnection != null, "Unexpected null connection argument on SetActiveConnectionAndResult!");
272275
TdsParser parser = activeConnection?.Parser;
276+
SqlClientEventSource.Log.TryTraceEvent("SqlCommand.SetActiveConnectionAndResult | API | ObjectId {0}, Client Connection Id {1}, MARS={2}", activeConnection?.ObjectID, activeConnection?.ClientConnectionId, parser?.MARSOn);
273277
if ((parser == null) || (parser.State == TdsParserState.Closed) || (parser.State == TdsParserState.Broken))
274278
{
275279
throw ADP.ClosedConnectionError();
@@ -1011,8 +1015,12 @@ protected override DbParameter CreateDbParameter()
10111015
protected override void Dispose(bool disposing)
10121016
{
10131017
if (disposing)
1014-
{ // release managed objects
1018+
{
1019+
// release managed objects
10151020
_cachedMetaData = null;
1021+
1022+
// reset async cache information to allow a second async execute
1023+
_cachedAsyncState?.ResetAsyncState();
10161024
}
10171025
// release unmanaged objects
10181026
base.Dispose(disposing);
@@ -1271,14 +1279,22 @@ private void BeginExecuteNonQueryInternalReadStage(TaskCompletionSource<object>
12711279
cachedAsyncState.SetActiveConnectionAndResult(completion, nameof(EndExecuteNonQuery), _activeConnection);
12721280
_stateObj.ReadSni(completion);
12731281
}
1282+
1283+
catch (System.OutOfMemoryException e)
1284+
{
1285+
_activeConnection.Abort(e);
1286+
throw;
1287+
}
1288+
catch (System.StackOverflowException e)
1289+
{
1290+
_activeConnection.Abort(e);
1291+
throw;
1292+
}
12741293
catch (Exception)
12751294
{
12761295
// Similarly, if an exception occurs put the stateObj back into the pool.
12771296
// and reset async cache information to allow a second async execute
1278-
if (null != _cachedAsyncState)
1279-
{
1280-
_cachedAsyncState.ResetAsyncState();
1281-
}
1297+
_cachedAsyncState?.ResetAsyncState();
12821298
ReliablePutStateObject();
12831299
throw;
12841300
}
@@ -1287,7 +1303,9 @@ private void BeginExecuteNonQueryInternalReadStage(TaskCompletionSource<object>
12871303
private void VerifyEndExecuteState(Task completionTask, string endMethod, bool fullCheckForColumnEncryption = false)
12881304
{
12891305
Debug.Assert(completionTask != null);
1290-
1306+
SqlClientEventSource.Log.TryTraceEvent("SqlCommand.VerifyEndExecuteState | API | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}",
1307+
_activeConnection?.ObjectID, _activeConnection?.ClientConnectionId,
1308+
_activeConnection?.Parser?.MARSOn, _activeConnection?.AsyncCommandInProgress);
12911309
if (completionTask.IsCanceled)
12921310
{
12931311
if (_stateObj != null)
@@ -1460,6 +1478,9 @@ private int EndExecuteNonQueryInternal(IAsyncResult asyncResult)
14601478

14611479
private object InternalEndExecuteNonQuery(IAsyncResult asyncResult, bool isInternal, [CallerMemberName] string endMethod = "")
14621480
{
1481+
SqlClientEventSource.Log.TryTraceEvent("SqlCommand.InternalEndExecuteNonQuery | INFO | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}",
1482+
_activeConnection?.ObjectID, _activeConnection?.ClientConnectionId,
1483+
_activeConnection?.Parser?.MARSOn, _activeConnection?.AsyncCommandInProgress);
14631484
VerifyEndExecuteState((Task)asyncResult, endMethod);
14641485
WaitForAsyncResults(asyncResult, isInternal);
14651486

@@ -1544,6 +1565,9 @@ private object InternalEndExecuteNonQuery(IAsyncResult asyncResult, bool isInter
15441565

15451566
private Task InternalExecuteNonQuery(TaskCompletionSource<object> completion, bool sendToPipe, int timeout, out bool usedCache, bool asyncWrite = false, bool inRetry = false, [CallerMemberName] string methodName = "")
15461567
{
1568+
SqlClientEventSource.Log.TryTraceEvent("SqlCommand.InternalExecuteNonQuery | INFO | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}",
1569+
_activeConnection?.ObjectID, _activeConnection?.ClientConnectionId,
1570+
_activeConnection?.Parser?.MARSOn, _activeConnection?.AsyncCommandInProgress);
15471571
bool isAsync = (null != completion);
15481572
usedCache = false;
15491573

@@ -1780,14 +1804,23 @@ private void BeginExecuteXmlReaderInternalReadStage(TaskCompletionSource<object>
17801804
_cachedAsyncState.SetActiveConnectionAndResult(completion, nameof(EndExecuteXmlReader), _activeConnection);
17811805
_stateObj.ReadSni(completion);
17821806
}
1807+
catch (System.OutOfMemoryException e)
1808+
{
1809+
_activeConnection.Abort(e);
1810+
completion.TrySetException(e);
1811+
throw;
1812+
}
1813+
catch (System.StackOverflowException e)
1814+
{
1815+
_activeConnection.Abort(e);
1816+
completion.TrySetException(e);
1817+
throw;
1818+
}
17831819
catch (Exception e)
17841820
{
17851821
// Similarly, if an exception occurs put the stateObj back into the pool.
17861822
// and reset async cache information to allow a second async execute
1787-
if (null != _cachedAsyncState)
1788-
{
1789-
_cachedAsyncState.ResetAsyncState();
1790-
}
1823+
_cachedAsyncState?.ResetAsyncState();
17911824
ReliablePutStateObject();
17921825
completion.TrySetException(e);
17931826
}
@@ -2034,6 +2067,9 @@ internal SqlDataReader EndExecuteReaderAsync(IAsyncResult asyncResult)
20342067

20352068
private SqlDataReader EndExecuteReaderInternal(IAsyncResult asyncResult)
20362069
{
2070+
SqlClientEventSource.Log.TryTraceEvent("SqlCommand.EndExecuteReaderInternal | API | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}",
2071+
_activeConnection?.ObjectID, _activeConnection?.ClientConnectionId,
2072+
_activeConnection?.Parser?.MARSOn, _activeConnection?.AsyncCommandInProgress);
20372073
SqlStatistics statistics = null;
20382074
bool success = false;
20392075
int? sqlExceptionNumber = null;
@@ -2404,28 +2440,41 @@ long firstAttemptStart
24042440
private void BeginExecuteReaderInternalReadStage(TaskCompletionSource<object> completion)
24052441
{
24062442
Debug.Assert(completion != null, "CompletionSource should not be null");
2443+
SqlClientEventSource.Log.TryCorrelationTraceEvent("SqlCommand.BeginExecuteReaderInternalReadStage | INFO | Correlation | Object Id {0}, Activity Id {1}, Client Connection Id {2}, Command Text '{3}'", ObjectID, ActivityCorrelator.Current, Connection?.ClientConnectionId, CommandText);
24072444
// Read SNI does not have catches for async exceptions, handle here.
24082445
try
24092446
{
24102447
// must finish caching information before ReadSni which can activate the callback before returning
24112448
cachedAsyncState.SetActiveConnectionAndResult(completion, nameof(EndExecuteReader), _activeConnection);
24122449
_stateObj.ReadSni(completion);
24132450
}
2451+
catch (System.OutOfMemoryException e)
2452+
{
2453+
_activeConnection.Abort(e);
2454+
completion.TrySetException(e);
2455+
throw;
2456+
}
2457+
catch (System.StackOverflowException e)
2458+
{
2459+
_activeConnection.Abort(e);
2460+
completion.TrySetException(e);
2461+
throw;
2462+
}
24142463
catch (Exception e)
24152464
{
24162465
// Similarly, if an exception occurs put the stateObj back into the pool.
24172466
// and reset async cache information to allow a second async execute
2418-
if (null != _cachedAsyncState)
2419-
{
2420-
_cachedAsyncState.ResetAsyncState();
2421-
}
2467+
_cachedAsyncState?.ResetAsyncState();
24222468
ReliablePutStateObject();
24232469
completion.TrySetException(e);
24242470
}
24252471
}
24262472

24272473
private SqlDataReader InternalEndExecuteReader(IAsyncResult asyncResult, bool isInternal, string endMethod)
24282474
{
2475+
SqlClientEventSource.Log.TryTraceEvent("SqlCommand.InternalEndExecuteReader | INFO | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}",
2476+
_activeConnection?.ObjectID, _activeConnection?.ClientConnectionId,
2477+
_activeConnection?.Parser?.MARSOn, _activeConnection?.AsyncCommandInProgress);
24292478
VerifyEndExecuteState((Task)asyncResult, endMethod);
24302479
WaitForAsyncResults(asyncResult, isInternal);
24312480

src/Microsoft.Data.SqlClient/netcore/src/Microsoft/Data/SqlClient/TdsParserStateObject.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2873,6 +2873,7 @@ public void ReadAsyncCallback(IntPtr key, PacketHandle packet, uint error)
28732873
// to the outstanding GCRoot until AppDomain.Unload.
28742874
// We live with the above for the time being due to the constraints of the current
28752875
// reliability infrastructure provided by the CLR.
2876+
SqlClientEventSource.Log.TryTraceEvent("TdsParserStateObject.ReadAsyncCallback | Info | State Object Id {0}, received error {1} on idle connection", _objectID, (int)error);
28762877

28772878
TaskCompletionSource<object> source = _networkPacketTaskSource;
28782879
#if DEBUG

src/Microsoft.Data.SqlClient/netfx/src/Microsoft/Data/SqlClient/SqlCommand.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,9 @@ internal bool IsActiveConnectionValid(SqlConnection activeConnection)
223223
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
224224
internal void ResetAsyncState()
225225
{
226+
SqlClientEventSource.Log.TryTraceEvent("CachedAsyncState.ResetAsyncState | API | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}",
227+
_cachedAsyncConnection?.ObjectID, _cachedAsyncConnection?.ClientConnectionId,
228+
_cachedAsyncConnection?.Parser?.MARSOn, _cachedAsyncConnection?.AsyncCommandInProgress);
226229
_cachedAsyncCloseCount = -1;
227230
_cachedAsyncResult = null;
228231
if (_cachedAsyncConnection != null)
@@ -240,6 +243,7 @@ internal void SetActiveConnectionAndResult(TaskCompletionSource<object> completi
240243
{
241244
Debug.Assert(activeConnection != null, "Unexpected null connection argument on SetActiveConnectionAndResult!");
242245
TdsParser parser = activeConnection.Parser;
246+
SqlClientEventSource.Log.TryTraceEvent("SqlCommand.SetActiveConnectionAndResult | API | ObjectId {0}, Client Connection Id {1}, MARS={2}", activeConnection?.ObjectID, activeConnection?.ClientConnectionId, parser?.MARSOn);
243247
if ((parser == null) || (parser.State == TdsParserState.Closed) || (parser.State == TdsParserState.Broken))
244248
{
245249
throw ADP.ClosedConnectionError();
@@ -1334,6 +1338,9 @@ protected override void Dispose(bool disposing)
13341338
if (disposing)
13351339
{ // release managed objects
13361340
_cachedMetaData = null;
1341+
1342+
// reset async cache information to allow a second async execute
1343+
_cachedAsyncState?.ResetAsyncState();
13371344
}
13381345
// release unmanaged objects
13391346
base.Dispose(disposing);
@@ -1645,6 +1652,9 @@ private void BeginExecuteNonQueryInternalReadStage(TaskCompletionSource<object>
16451652
private void VerifyEndExecuteState(Task completionTask, string endMethod, bool fullCheckForColumnEncryption = false)
16461653
{
16471654
Debug.Assert(completionTask != null);
1655+
SqlClientEventSource.Log.TryTraceEvent("SqlCommand.VerifyEndExecuteState | API | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}",
1656+
_activeConnection?.ObjectID, _activeConnection?.ClientConnectionId,
1657+
_activeConnection?.Parser?.MARSOn, _activeConnection?.AsyncCommandInProgress);
16481658

16491659
if (completionTask.IsCanceled)
16501660
{
@@ -1812,6 +1822,9 @@ private int EndExecuteNonQueryInternal(IAsyncResult asyncResult)
18121822

18131823
private object InternalEndExecuteNonQuery(IAsyncResult asyncResult, string endMethod, bool isInternal)
18141824
{
1825+
SqlClientEventSource.Log.TryTraceEvent("SqlCommand.InternalEndExecuteNonQuery | INFO | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}",
1826+
_activeConnection?.ObjectID, _activeConnection?.ClientConnectionId,
1827+
_activeConnection?.Parser?.MARSOn, _activeConnection?.AsyncCommandInProgress);
18151828
TdsParser bestEffortCleanupTarget = null;
18161829
RuntimeHelpers.PrepareConstrainedRegions();
18171830

@@ -1932,6 +1945,9 @@ private object InternalEndExecuteNonQuery(IAsyncResult asyncResult, string endMe
19321945

19331946
private Task InternalExecuteNonQuery(TaskCompletionSource<object> completion, string methodName, bool sendToPipe, int timeout, out bool usedCache, bool asyncWrite = false, bool inRetry = false)
19341947
{
1948+
SqlClientEventSource.Log.TryTraceEvent("SqlCommand.InternalExecuteNonQuery | INFO | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}",
1949+
_activeConnection?.ObjectID, _activeConnection?.ClientConnectionId,
1950+
_activeConnection?.Parser?.MARSOn, _activeConnection?.AsyncCommandInProgress);
19351951
bool async = (null != completion);
19361952
usedCache = false;
19371953

@@ -2550,6 +2566,9 @@ private SqlDataReader EndExecuteReaderAsync(IAsyncResult asyncResult)
25502566

25512567
private SqlDataReader EndExecuteReaderInternal(IAsyncResult asyncResult)
25522568
{
2569+
SqlClientEventSource.Log.TryTraceEvent("SqlCommand.EndExecuteReaderInternal | API | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}",
2570+
_activeConnection?.ObjectID, _activeConnection?.ClientConnectionId,
2571+
_activeConnection?.Parser?.MARSOn, _activeConnection?.AsyncCommandInProgress);
25532572
SqlStatistics statistics = null;
25542573
bool success = false;
25552574
int? sqlExceptionNumber = null;
@@ -2801,6 +2820,7 @@ private bool TriggerInternalEndAndRetryIfNecessary(CommandBehavior behavior, obj
28012820
private void BeginExecuteReaderInternalReadStage(TaskCompletionSource<object> completion)
28022821
{
28032822
Debug.Assert(completion != null, "CompletionSource should not be null");
2823+
SqlClientEventSource.Log.TryCorrelationTraceEvent("SqlCommand.BeginExecuteReaderInternalReadStage | INFO | Correlation | Object Id {0}, Activity Id {1}, Client Connection Id {2}, Command Text '{3}'", ObjectID, ActivityCorrelator.Current, Connection?.ClientConnectionId, CommandText);
28042824
// Read SNI does not have catches for async exceptions, handle here.
28052825
TdsParser bestEffortCleanupTarget = null;
28062826
RuntimeHelpers.PrepareConstrainedRegions();
@@ -2862,6 +2882,9 @@ private void BeginExecuteReaderInternalReadStage(TaskCompletionSource<object> co
28622882

28632883
private SqlDataReader InternalEndExecuteReader(IAsyncResult asyncResult, string endMethod, bool isInternal)
28642884
{
2885+
SqlClientEventSource.Log.TryTraceEvent("SqlCommand.InternalEndExecuteReader | INFO | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}",
2886+
_activeConnection?.ObjectID, _activeConnection?.ClientConnectionId,
2887+
_activeConnection?.Parser?.MARSOn, _activeConnection?.AsyncCommandInProgress);
28652888
VerifyEndExecuteState((Task)asyncResult, endMethod);
28662889
WaitForAsyncResults(asyncResult, isInternal);
28672890

0 commit comments

Comments
 (0)