0

I am occationally getting a null reference exception when running my bitcoin node (written in C# .NET 4.5). I have been trying various apporaches, but it keeps coming up, sometimes after a few hours, sometimes after the server has been running uninterrupted for days. I am unable to provoke the issue (cannot reproduce), and I cannot see the source of the .NET implementation of the red-black-tree either. It seems it could be an internal .NET bug related to clearing a dataset. I have an exception trace here. I would appreciate any feedback on how to either correct the issue or work around it, in case anyone has had the same odd experience.

HResult:           -2146233088, 0x80131500
Exception Source:  
Exception Origin:  
Exception Stack:
    Exception Type:    Slf.Cs.SlfInternalErrorException
    Exception Message: SelectData with SELECT statement: "SELECT * FROM [dbo].[BlockHeaders] WHERE BlockHash = @EqualToValue" failed.
    SlfException Info: 
    HResult:           -2146233088, 0x80131500
    Exception Source:  Slf.Cs
    Exception Origin:  Int32 SelectData(System.Data.SqlClient.SqlConnection, Int32, System.Data.DataTable, System.String, System.Data.SqlClient.SqlParameter[])
    Exception Stack:   at Slf.Cs.SlfSqlUtilities.SelectData(SqlConnection connection, Int32 timeoutSeconds, DataTable dataTable, String selectStatement, SqlParameter[] parameters) in C:\Data Files\Development Projects\iProtus\Frameworks\Slf.Cs\System\Basics\SlfUtilities.cs:line 1231
                       at Slf.Cs.Data.SlfSqlTable`1.Select(String columnName, Object equalToValue, Int32 maxCount, String orderByStatement) in C:\Data Files\Development Projects\iProtus\Frameworks\Slf.Cs\System\Database\SqlServer\SlfSqlDatabase.cs:line 950
                       at Slf.Cs.CryptCoin.BlockchainDB.GetDbBlockHeadersByBlockHash(Byte[] headerHash) in C:\Data Files\Development Projects\iProtus\Frameworks\Slf.Cs.CryptCoin\Basics\BlockchainDB.cs:line 212
                       at Slf.Cs.CryptCoin.BlockchainDB.GetBlockHeight(SlfByte32 blockHash) in C:\Data Files\Development Projects\iProtus\Frameworks\Slf.Cs.CryptCoin\Basics\BlockchainDB.cs:line 856
                       at Slf.Cs.CryptCoin.BitcoinStore.GetBlockHeight(SlfByte32 hash) in C:\Data Files\Development Projects\iProtus\Frameworks\Slf.Cs.CryptCoin\Basics\BitcoinStore.cs:line 597
                       at Slf.Cs.CryptCoin.BitcoinPeer.ExecuteGetHeadersCommand(BitcoinMessage message) in C:\Data Files\Development Projects\iProtus\Frameworks\Slf.Cs.CryptCoin\Network\BitcoinPeer.cs:line 829
                       at Slf.Cs.CryptCoin.BitcoinPeer.ExecuteCommand(BitcoinMessage message) in C:\Data Files\Development Projects\iProtus\Frameworks\Slf.Cs.CryptCoin\Network\BitcoinPeer.cs:line 1223
                       at Slf.Cs.CryptCoin.BitcoinPeer.ProcessNextCommand() in C:\Data Files\Development Projects\iProtus\Frameworks\Slf.Cs.CryptCoin\Network\BitcoinPeer.cs:line 1591
                       at Slf.Cs.CryptCoin.BitcoinPeer.Run(Object userContext) in C:\Data Files\Development Projects\iProtus\Frameworks\Slf.Cs.CryptCoin\Network\BitcoinPeer.cs:line 1740
                       at Slf.Cs.CryptCoin.BitcoinNode.Peer(PeerContext context) in C:\Data Files\Development Projects\iProtus\Frameworks\Slf.Cs.CryptCoin\Network\BitcoinNode.cs:line 857
                       at Slf.Cs.SlfPeerToPeerNode.InternalPeerThread(PeerContext context) in C:\Data Files\Development Projects\iProtus\Frameworks\Slf.Cs\System\Network\SlfPeerToPeerNode.cs:line 1977
        Exception Type:    System.NullReferenceException
        Exception Message: Object reference not set to an instance of an object.
        HResult:           -2147467261, 0x80004003
        Exception Source:  System.Data
        Exception Origin:  Int32 Minimum(Int32)
        Exception Stack:   at System.Data.RBTree`1.Minimum(Int32 x_id)
                           at System.Data.RBTree`1.Successor(Int32& nodeId, Int32& mainTreeNodeId)
                           at System.Data.RBTree`1.RBTreeEnumerator.MoveNext()
                           at System.Data.Index.InitRecords(IFilter filter)
                           at System.Data.Index.Reset()
                           at System.Data.DataTable.ResetInternalIndexes(DataColumn column)
                           at System.Data.DataTable.Clear(Boolean clearAll)
                           at System.Data.DataTable.Clear()
                           at Slf.Cs.SlfSqlUtilities.FillDataTable(SqlDataAdapter adapter, DataTable dataTable) in C:\Data Files\Development Projects\iProtus\Frameworks\Slf.Cs\System\Basics\SlfUtilities.cs:line 1299
                           at Slf.Cs.SlfSqlUtilities.SelectData(SqlConnection connection, Int32 timeoutSeconds, DataTable dataTable, String selectStatement, SqlParameter[] parameters) in C:\Data Files\Development Projects\iProtus\Frameworks\Slf.Cs\System\Basics\SlfUtilities.cs:line 1222

--Edit, due to nature of initial comments--

Look at the innermost exception trace. This is a call to the standard DataTable.Clear() method, that is supposed to remove all from a DataTable. The rest doesn't really matter. In hindsight, I should have just posted that innermost exception.

Furthermore, I do not see the need to provide sample code, as one requested, since it obviously is internal to .NET. Most likely it is concurrency related, which I tried circumvent by wrapping all my DataTable.Clear() calls in a lock on a static object, and it still happens. The fact that it happens rarely and with random intervals is another good indication that concurrency is the issue. However, trying everything, I finally gave up and posted here, hoping someone else has this issue solved :)

Søren L. Fog
  • 289
  • 3
  • 4
  • 3
    The null-ref is internal to the .NET Framework, I don't think the canonical "what is a null ref" question is applicable here. – vcsjones Jul 01 '15 at 18:41
  • 4
    Also, regarding the actual question, typically I've seen this when a DataTable is used from multiple threads. DataTables are not thread safe. – vcsjones Jul 01 '15 at 18:42
  • 1
    We can't analyze this without any code. – CodeCaster Jul 01 '15 at 18:43
  • Thanks for the insight. As to providing code, I really see no need. Any code calling DataTable.Clear() would do. Perhaps I shouldn't have posted the entire stacktrace but just the innermost exception - that really explains the problem. As vcsjones states, this is internal to .NET, and my best guess too is it may have something to do with concurrency. However, I tried to surround the call with a lock on a static object, and no change. Reproducing is impossible. The problem has also been posted to Microsoft, but I'm getting standard copy/paste replies from them only. – Søren L. Fog Jul 03 '15 at 12:50

0 Answers0