Skip to content

Commit 3d99070

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

File tree

4 files changed

+105
-14
lines changed

4 files changed

+105
-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: 62 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,8 @@ 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}, AsyncCommandInProgress={2}",
1569+
_activeConnection?.ObjectID, _activeConnection?.ClientConnectionId, _activeConnection?.AsyncCommandInProgress);
15471570
bool isAsync = (null != completion);
15481571
usedCache = false;
15491572

@@ -1780,14 +1803,23 @@ private void BeginExecuteXmlReaderInternalReadStage(TaskCompletionSource<object>
17801803
_cachedAsyncState.SetActiveConnectionAndResult(completion, nameof(EndExecuteXmlReader), _activeConnection);
17811804
_stateObj.ReadSni(completion);
17821805
}
1806+
catch (System.OutOfMemoryException e)
1807+
{
1808+
_activeConnection.Abort(e);
1809+
completion.TrySetException(e);
1810+
throw;
1811+
}
1812+
catch (System.StackOverflowException e)
1813+
{
1814+
_activeConnection.Abort(e);
1815+
completion.TrySetException(e);
1816+
throw;
1817+
}
17831818
catch (Exception e)
17841819
{
17851820
// Similarly, if an exception occurs put the stateObj back into the pool.
17861821
// and reset async cache information to allow a second async execute
1787-
if (null != _cachedAsyncState)
1788-
{
1789-
_cachedAsyncState.ResetAsyncState();
1790-
}
1822+
_cachedAsyncState?.ResetAsyncState();
17911823
ReliablePutStateObject();
17921824
completion.TrySetException(e);
17931825
}
@@ -2034,6 +2066,9 @@ internal SqlDataReader EndExecuteReaderAsync(IAsyncResult asyncResult)
20342066

20352067
private SqlDataReader EndExecuteReaderInternal(IAsyncResult asyncResult)
20362068
{
2069+
SqlClientEventSource.Log.TryTraceEvent("SqlCommand.EndExecuteReaderInternal | API | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}",
2070+
_activeConnection?.ObjectID, _activeConnection?.ClientConnectionId,
2071+
_activeConnection?.Parser?.MARSOn, _activeConnection?.AsyncCommandInProgress);
20372072
SqlStatistics statistics = null;
20382073
bool success = false;
20392074
int? sqlExceptionNumber = null;
@@ -2404,28 +2439,41 @@ long firstAttemptStart
24042439
private void BeginExecuteReaderInternalReadStage(TaskCompletionSource<object> completion)
24052440
{
24062441
Debug.Assert(completion != null, "CompletionSource should not be null");
2442+
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);
24072443
// Read SNI does not have catches for async exceptions, handle here.
24082444
try
24092445
{
24102446
// must finish caching information before ReadSni which can activate the callback before returning
24112447
cachedAsyncState.SetActiveConnectionAndResult(completion, nameof(EndExecuteReader), _activeConnection);
24122448
_stateObj.ReadSni(completion);
24132449
}
2450+
catch (System.OutOfMemoryException e)
2451+
{
2452+
_activeConnection.Abort(e);
2453+
completion.TrySetException(e);
2454+
throw;
2455+
}
2456+
catch (System.StackOverflowException e)
2457+
{
2458+
_activeConnection.Abort(e);
2459+
completion.TrySetException(e);
2460+
throw;
2461+
}
24142462
catch (Exception e)
24152463
{
24162464
// Similarly, if an exception occurs put the stateObj back into the pool.
24172465
// and reset async cache information to allow a second async execute
2418-
if (null != _cachedAsyncState)
2419-
{
2420-
_cachedAsyncState.ResetAsyncState();
2421-
}
2466+
_cachedAsyncState?.ResetAsyncState();
24222467
ReliablePutStateObject();
24232468
completion.TrySetException(e);
24242469
}
24252470
}
24262471

24272472
private SqlDataReader InternalEndExecuteReader(IAsyncResult asyncResult, bool isInternal, string endMethod)
24282473
{
2474+
SqlClientEventSource.Log.TryTraceEvent("SqlCommand.InternalEndExecuteReader | INFO | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}",
2475+
_activeConnection?.ObjectID, _activeConnection?.ClientConnectionId,
2476+
_activeConnection?.Parser?.MARSOn, _activeConnection?.AsyncCommandInProgress);
24292477
VerifyEndExecuteState((Task)asyncResult, endMethod);
24302478
WaitForAsyncResults(asyncResult, isInternal);
24312479

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: 22 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,8 @@ 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}, AsyncCommandInProgress={2}",
1949+
_activeConnection?.ObjectID, _activeConnection?.ClientConnectionId, _activeConnection?.AsyncCommandInProgress);
19351950
bool async = (null != completion);
19361951
usedCache = false;
19371952

@@ -2550,6 +2565,9 @@ private SqlDataReader EndExecuteReaderAsync(IAsyncResult asyncResult)
25502565

25512566
private SqlDataReader EndExecuteReaderInternal(IAsyncResult asyncResult)
25522567
{
2568+
SqlClientEventSource.Log.TryTraceEvent("SqlCommand.EndExecuteReaderInternal | API | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}",
2569+
_activeConnection?.ObjectID, _activeConnection?.ClientConnectionId,
2570+
_activeConnection?.Parser?.MARSOn, _activeConnection?.AsyncCommandInProgress);
25532571
SqlStatistics statistics = null;
25542572
bool success = false;
25552573
int? sqlExceptionNumber = null;
@@ -2801,6 +2819,7 @@ private bool TriggerInternalEndAndRetryIfNecessary(CommandBehavior behavior, obj
28012819
private void BeginExecuteReaderInternalReadStage(TaskCompletionSource<object> completion)
28022820
{
28032821
Debug.Assert(completion != null, "CompletionSource should not be null");
2822+
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);
28042823
// Read SNI does not have catches for async exceptions, handle here.
28052824
TdsParser bestEffortCleanupTarget = null;
28062825
RuntimeHelpers.PrepareConstrainedRegions();
@@ -2862,6 +2881,9 @@ private void BeginExecuteReaderInternalReadStage(TaskCompletionSource<object> co
28622881

28632882
private SqlDataReader InternalEndExecuteReader(IAsyncResult asyncResult, string endMethod, bool isInternal)
28642883
{
2884+
SqlClientEventSource.Log.TryTraceEvent("SqlCommand.InternalEndExecuteReader | INFO | ObjectId {0}, Client Connection Id {1}, MARS={2}, AsyncCommandInProgress={3}",
2885+
_activeConnection?.ObjectID, _activeConnection?.ClientConnectionId,
2886+
_activeConnection?.Parser?.MARSOn, _activeConnection?.AsyncCommandInProgress);
28652887
VerifyEndExecuteState((Task)asyncResult, endMethod);
28662888
WaitForAsyncResults(asyncResult, isInternal);
28672889

0 commit comments

Comments
 (0)