.SqlDataReader.ReadColumnHeader NullReferenceException - ado.net

This question is somewhat related to my previous one answer to which helped me to find the reason why this simple iteration thru SqlDataReader:
m_aFullIDList = New Generic.List(Of Integer)
While i_oDataReader.Read
m_aFullIDList.Add(i_oDataReader.GetInt32(0))
End While
m_iTotalNumberOfRecords = m_aFullIDList.Count
does not return all the records. Turned out when Generic.List changes its Capacity to accommodate more elements (e.g from 2^19 to next one 2^20) at this point SqlDataReader simple quits, its Read method returns False as if there's no more records.
Most of the time it quits quietly, no exception is thrown whatsoever. But every now and then I'd get:
NullReferenceException {"Object reference not set to an instance of an
object."}
at System.Data.SqlClient.SqlDataReader.ReadColumnHeader(Int32 i)
at System.Data.SqlClient.SqlDataReader.ReadColumn(Int32 i, Boolean
setTimeout) at System.Data.SqlClient.SqlDataReader.GetInt32(Int32 i)
I know for a fact that all records returned by Stored Procedure used by the Reader (it's a single column) are integer values. If I remove line m_aFullIDList.Add and instead simple read value into an integer variable OR if I pre-allocate Generic List capacity to a know large number - this issue is not happening. Apparently it only happens when List reallocates Capacity - this affects the reader.
I also attempted to use other structures (ArrayList, even Array, using Array.Resize) as soon as capacity of this structure is reallocated beyond certain point - this breaks the SqlDataReader.
This ASP.NET project is kinda complex, so when I tried to recreate the issue in a standalone simple project consisting only of executing reader and reading into List - the issue is not happening. Any idea what is going on and how this could be fixed?

I think I finally figured it out.
The logic in my code had 2 steps - call the function that returns SqlDataReader and then use that reader in another function to fill the list:
Dim oReader as SqlDataReader = GetTheReader()
FillTheList(oReader)
Function GetTheReader() looked something like this:
Function GetTheReader() as SqlDataReader
Dim oConn As New SqlConnection("Connection String") : oConn.Open()
Dim oComm As New SqlCommand("Stored Procedure", oConn)
Dim oReader As SqlDataReader = oComm.ExecuteReader(CommandBehavior.CloseConnection)
Return oReader
End Function
It opened connection as a local variable which went out of scope when the function returned back to the caller. And when Generic List was being populated, after another Capacity allocation Garbage Collection claimed that memory by destroying outdated variables (and closing that connection). I was left with a SqlDataReader without a valid connection.
My current solution is to create connection outside GetTheReader function and pass it as one of the parameters.

Related

q/kdb - hitting 'constants error when adding new key-value assignments to a dictionary within a function

I am currently working on a script where within a function, key-value pairs are being added to a dictionary x - consider x as a single dictionary of different inputs used to query data, and different key-values are appended to this depending on certain conditions being fulfilled.
However, when I load in the script into my session with some new assignment logic added, I am hitting a 'constants error. This is despite all assignments being kept to this dictionary x. When these two new assignments within x are commented out, the script will load in successfully.
I know the 'constants error usually refers to the max number of constants within a certain scope being exceeded, but surely this shouldn't be happening when all assignment is happening within this dictionary x. Is there a way to get around this? What is causing this issue?
I think you are trying to do too much in one function. I think you are indexing or assigning values to the dictionary with too many constants. Below code will return the constants error:
dict:(10 + til 100)!til 100
value (raze -1_"{","dict[",/:(string[10+til 97],\:"];")),"}"
// with til 96
{dict[10];dict[11] ... dict[104]}
It's the code that is indexing the dictionary is causing the issue rather than the dictionary itself.

Does string concatenation in Swift make a new copy?

I can concatenate two strings in Swift like this:
var c = "Hello World"
c += "!"
Does this create a new string? (Allocating a new block of memory, copying over the original string, concatenating the "!" string and returning the new memory.) Or, does it update the original string in place (only allocating a new block of memory if the original block can't fit the character).
No, it does not make a new copy. As you can see, the original string has changed.But the address remains same.
As it says in the apple documentation : https://developer.apple.com/documentation/swift/string
in the section of Performance optimizations:
"Although strings in Swift have value semantics, strings use a copy-on-write strategy to store their data in a buffer. This buffer can then be shared by different copies of a string. A string’s data is only copied lazily, upon mutation, when more than one string instance is using the same buffer. Therefore, the first in any sequence of mutating operations may cost O(n) time and space."
IOs use copy-on-write so if more than 1 process use the same variable, or has more than 1 copy (i don't fully understand this part), it makes a copy, but if the variable is only used for 1 process and has only one copy, then you can mutate it as you wish without generating copies

Eval() for setting Form controls property

I work on an Access VBA 2013 application, and this part of the project focuses on form controls and buttons.
I want to lock/unlock control modification thanks to buttons set aside.
For more genericity, I wanted the subs called by the events call homemade functions:
Sub LockAssociateControl(fctName As String, val As Boolean)
Dim code As String
code = "Forms!" & getModuleName & ".Controls!" & fctName & ".Locked = " & CStr(val)
Debug.Print (code) 'just to test
Eval code
End Sub
(getModuleName is also a homemade function that returns the right name of the module calling the function)
For example, this one is called like below:
Private Sub FirstName_Exit(Cancel As Integer)
Call LockAssociateControl("FirstName", True)
End Sub
and in "code" variable, it sets "Forms!Module1.Controls!Name.Locked = True" (with Module1 generated by getModuleName, and Name as the parameter (I haven't found better yet)).
Now I want this code evaluated in order to avoid me from hard coding every event sub.
My problem is that an error occurs at the Eval() line and says:
Error Code: 2770. The object to which you reffered in the Visual Basic procedure as an OLE object is not an OLE object
I've looked around StockOverflow and others forums to find out what's wrong with Eval(), and I found that this function's behavior is not made for what I want. So I tried to find another way to do that, as Evaluate function doesn't exist in Access, etc, but I found nothing really helpful.
I tried to use DoCmd or Call or various transformations on the parameter string of Eval(), but nothing has worked so far...
So here's my question: Do any of you have a solution for that problem? And if not, do you know an alternative not to have to write in every event function full statements like: Forms!Module1.Controls!Name.Locked = False?
You can do what you want easier without using Eval() ...
Sub LockAssociateControl(fctName As String, pVal As Boolean)
Forms(getModuleName).Controls(fctName).Locked = pVal
End Sub
Note I changed the argument name from val to pVal to avoid confusing it with the Val() function.

Breaking when a method returns null in the Eclipse debugger

I'm working on an expression evaluator. There is an evaluate() function which is called many times depending on the complexity of the expression processed.
I need to break and investigate when this method returns null. There are many paths and return statements.
It is possible to break on exit method event but I can't find how to put a condition about the value returned.
I got stuck in that frustration too. One can inspect (and write conditions) on named variables, but not on something unnamed like a return value. Here are some ideas (for whoever might be interested):
One could include something like evaluate() == null in the breakpoint's condition. Tests performed (Eclipse 4.4) show that in such a case, the function will be performed again for the breakpoint purposes, but this time with the breakpoint disabled. So you will avoid a stack overflow situation, at least. Whether this would be useful, depends on the nature of the function under consideration - will it return the same value at breakpoint time as at run time? (Some s[a|i]mple code to test:)
class TestBreakpoint {
int counter = 0;
boolean eval() { /* <== breakpoint here, [x]on exit, [x]condition: eval()==false */
System.out.println("Iteration " + ++counter);
return true;
}
public static void main(String[] args) {
TestBreakpoint app = new TestBreakpoint();
System.out.println("STARTED");
app.eval();
System.out.println("STOPPED");
}
}
// RESULTS:
// Normal run: shows 1 iteration of eval()
// Debug run: shows 2 iterations of eval(), no stack overflow, no stop on breakpoint
Another way to make it easier (to potentially do debugging in future) would be to have coding conventions (or personal coding style) that require one to declare a local variable that is set inside the function, and returned only once at the end. E.g.:
public MyType evaluate() {
MyType result = null;
if (conditionA) result = new MyType('A');
else if (conditionB) result = new MyType ('B');
return result;
}
Then you can at least do an exit breakpoint with a condition like result == null. However, I agree that this is unnecessarily verbose for simple functions, is a bit contrary to flow that the language allows, and can only be enforced manually. (Personally, I do use this convention sometimes for more complex functions (the name result 'reserved' just for this use), where it may make things clearer, but not for simple functions. But it's difficult to draw the line; just this morning had to step through a simple function to see which of 3 possible cases was the one fired. For today's complex systems, one wants to avoid stepping.)
Barring the above, you would need to modify your code on a case by case basis as in the previous point for the single function to assign your return value to some variable, which you can test. If some work policy disallows you to make such non-functional changes, one is quite stuck... It is of course also possible that such a rewrite could result in a bug inadvertently being resolved, if the original code was a bit convoluted, so beware of reverting to the original after debugging, only to find that the bug is now back.
You didn't say what language you were working in. If it's Java or C++ you can set a condition on a Method (or Function) breakpoint using the breakpoint properties. Here are images showing both cases.
In the Java example you would unclik Entry and put a check in Exit.
Java Method Breakpoint Properties Dialog
!
C++ Function Breakpoint Properties Dialog
This is not yet supported by the Eclipse debugger and added as an enhancement request. I'd appreciate if you vote for it.
https://bugs.eclipse.org/bugs/show_bug.cgi?id=425744

Does casting an address to (id) have side-effects??? Is Address 0xbfffe8d0 special? (fixed: issue was with _NSCallStackArray)

The following line of code causes my program to break in a very strange way...
id foo = (id)0xbfffe8d0;
Yet, this is no problem:
int foo = (int)(id)0xbfffe8d0;
And even this is no problem:
int magicAddr = 0xbfffe8d0;
id foo = (id)magicAddr;
W. T. F. ?
Just inserting that line of code inside a particular init method causes my iteration through an array to fail with "NSGenericException: Collection was mutated while being enumerated". Commenting the line out causes the exception not to happen. This code is single-threaded. The behavior is deterministic and has consistently reproduced over and over again and consistently non-reproduced when I comment the line out. "foo" is a made-up variable and is never referenced again. No other code refers to "foo".
Does that line have a side-effect? Does casting a number to an (id) have some side-effect?
More details on what I was doing:
I ran NSLog(#"self=%p, super=%p", self, super) and it printed out "self=0xa83dc50, super=0xbfffe8d0", leading me to ask this question
I have _NO_IDEA_ what that 0xbfffe8d0 value is or means.
The line I pasted is inside a method init2 for a class that has a reference to the NSEnumerator over the collection which throws the Exception. The class does NOT mutate the collection or even have a reference to the collection.
The exact code: (removed, not relevant or interesting)
OK, so I still can't explain the behavior above. I can't explain why a 4-byte int on the stack is ok, but a 4-byte "id" is crashville. But I ran this code a few hundred times putting all manor of random crap in, and I was able to trigger crashes with other values and statements. Always deterministic, but no clear or explainable pattern for stuff that crashed vs stuff that didn't. Bizzare stuff, but not the ultimate issue.
The real issue? The collection was from [NSThread callStackSymbols]. That returns _NSCallStackArray. That's where the real Zebra lives. There's something funky about that pseudo-collection, but I couldn't tell you what exactly.
The fix?
[NSArray arrayWithArray: [NSThread callStackSymbols]]
With the fix, no combination of random crap in my code will trigger the enumeration crash. So beware. If you plan to return the call stack symbols and treat them as an array, MAKE A COPY.
The lesson? If you call [NSThread callStackSymbols] and want to treat the result like an array, MAKE A COPY and get a real array. Else, .... "there be dragons" !!
No. id is a typedef for a pointer type, and assigning to a pointer has no side effects. You have some other bug in your code somewhere else, it's impossible to say without seeing more code.
0xbfffe8d0 is a pointer to an address in your stack. When compiled without optimizations, the assignment does write the value 0xbffe8d0 into your stack, but that value then never gets read anywhere. So it does have the effect of (a) increasing that function's stack frame size by 4 bytes and (b) changing the size of the function's code and offsetting all of the subsequent code. Most likely these changes are causing the bug elsewhere in your program to appear or not appear.