Entire program not working due to one logical error - arm

I am using NEX Robotics board for LPC2148. I find very strange problem with below lines of code.
//Prototypes
void diaplayInRow1WithPosition(unsigned char* data, unsigned char position);
void diaplayInRow2WithPosition(unsigned char* data, unsigned char position);
unsigned char convertHigherNibbleToASCIIValue(unsigned char data);
unsigned char convertLowerNibbleToASCIIValue(unsigned char data);
int main (void)
{
unsigned char temp2;
unsigned int PLLStatus;
initializeAll();
PLLStatus = PLL0STAT;
temp2 = convertLowerNibbleToASCIIValue(PLLStatus);
diaplayInRow1WithPosition(&temp2,15);
temp2 = convertHigherNibbleToASCIIValue(PLLStatus);
diaplayInRow1WithPosition(&temp2,14);
temp2 = PLLStatus>>8;
temp2 = convertLowerNibbleToASCIIValue(PLLStatus);
diaplayInRow1WithPosition(&temp2,13);
return(0);
}
When this code is executed, I see a blank display. I noticed that the problem is with last convertLowerNibbleToASCIIValue function call. It should have been:
temp2 = convertLowerNibbleToASCIIValue(temp2 );
But because of this one line error, why entire display is blank? Only last function diaplayInRow1WithPosition should have given trouble right?
Even after changing with above line, I am getting blank display. So I replaced that line containing last convertLowerNibbleToASCIIValue as
temp2 = convertLowerNibbleToASCIIValue(PLLStatus>>8);
And finally I got correct display.
Unable to digest the problem. Anyone can help? Main answer I need is if at all there is a problem in one line, why previous lines are not getting executed correctly? I am using Keil compiler and any compiler dependencies? There is no compilation error.
If there is a problem with types etc, will entire program get corrupted?

More likely than your "entire program not working" is that either:
the display data is buffered and the program crashes before the buffered data reaches the display,
or simply that the value of PLLStatus is not displayable and has the effect of blanking the display or perhaps stops it working correctly altogether - it may not be a printable character, and we are given no information about the display hardware or its API, so the effect of garbage-in is undefined.

Finally found that the issue is with Keil compiler. If I add one additional dummy line (could be any assignment statement), code works!!! Somewhere some optimization is happening, but unable to make out where. Anyway I have work around now. Add one dummy if does not work and remove again if not needed!!!

Related

why my variable's value changes (i noticed when using debugger that the value changed)?

I am prompting the user for a card number and then applying some formula on this number but I noticed an expected change in the output as the variable's value changes during the running of the code without reassigning it
the variable 'long card' value changes.
long card = checkNumber();
const long card_to_use = card;
char card_name[0];
int cardL = (floor(log10(card)) + 1);
const int first_two_digits = card_to_use/myPow(10,cardL-2);
const int first_digit = card_to_use/myPow(10,cardL-1);
if(first_two_digits>=51 && first_two_digits<=55){
strcpy(card_name, "mastercard");
}else if (first_two_digits==37 || first_two_digits==34){
strcpy(card_name, "amex");
}else if(first_digit == 4){
strcpy(card_name, "visa");
}
the value changes when if(first_two_digits>=51 && first_two_digits<=55) is executed I don't know exactly why?
I tried to capture the value of it in const long card_to_use from the beginning but it also changed actually changed to a 19 digit number which is also surprising.
thanks for reading
p.s: I am using cs50 IDE
You've declared card_name as a zero-length char array on the stack. The strcpy() call is probably clobbering the other variables on the stack (eg. card_to_use) due to overflow.
As to how this is happening before the call to strcpy() when the debugger is claiming you're at the line with if (...), that's probably due to optimization. You can disable optimization using the -O0 compile flag on gcc and clang. Note that in this case, optimization is likely not causing the call to occur before the condition check. Some instruction corresponding to the condition check is probably executing after the call to strcpy().
I believe the problem is the definition of card_name. char card_name[0] doesn't allocate any space for the characters copied during the strcpy() step.
Try changing char card_name[0] to char card_name[30].
char card_name[0];
This array has zero space, specified by the [0]. When the program writes to the array it runs off the end, corrupting other things in the memory. Changing it to something like:
char card_name[20];
Would assign 20 char spaces in an array to work with, which looks like enough for your program.

Arduino function interfering with loop() code

I have, among others, the following lines in the loop function:
item = String(buffer);
Serial.println(item);
Where item is a String and buffer a char array. This works perfectly until I add a function at the end of the file (outside of the loop function):
void storeData(String item){
Serial.println("StoreData");
for (int k=0; k<11; k++){
Serial.print("*");
if(item == products[k]){
items[index] = names[k];
index++;
Serial.print("\n");
Serial.print(item);
Serial.print("\t");
Serial.print(names[k]);
}
}
}
Which compares the string item to a list of values and stores the corresponding name if the value is found.
When I add this code at the end, even if I DON'T call on the function, the output of the conversion becomes:
978973103 Á
9789731030418
Where the first value is the incorrect conversion and the second one is the value of buffer.
What could possibly be happening? I've restarted and rewired and redone everything from scratch over and over again.
It may be possible you are running out of the 2K SRAM. Arrays of Strings can quickly use it up.
Additionally I recommend using the F() function as not use use RAM for constanst. e.g. Serial.println(F("StoreData");
The latest IDE's show the expected RAM usage. but this is a guess. If it is even close then there is likely an issue. I use the following MemoryFree library at specific points in the code to reveal the highwater.
Since item is string. I think you can try using
Serial.println(item);
instead of
Serial.print(item);
in you storeData function. Also similarly for other strings

why does adding a printf("A") make my code run, and removing it makes it crash

I have the following code in C:
while(tempNode!=NULL) {
int pos = pathNodesCount-1-i;
pathNodes[pos] = tempNode;
//printf("A");
euclidianLength += tempNode->g;
i = i+1;
tempNode = tempNode->parent;
}
if I leave the printf("A") statement commented out, and then compile and run my code, I will get an "application stopped running" Windows error. If I uncomment the printf("A") line, recompile and run, the application will run to its end (printing "A" to the console along the way). Why?
The environment is:
Windows 7 32bit
MinGW32 20120426 (and I've added MSys 1.0)
Eclipse Juno for C/CPP
== UPDATE
I've tracked my error. I won't post the exact code as it is too long, but it was a case of creating a char array, and then adding characters at wrong indexes. Something like this:
int otherCrap() {
char* c = malloc(10*sizeof(char));
int i = 0;
for(i = 0; i<13; i++) {
c[i]='a';
}
c[15] = '\0';
printf("A");
printf(c);
return 0;
}
Fixing the thing so that the chars were placed inside the array only at existing indexes, and also ading '\0' char as the last element in the array fixed the issue. However I'm still not clear as to why, when the code was bad, adding a printf('A') before printing the char array didn't result in a runtime error. From the answers received so far I am to understand that this falls under "undefined behavior".
Probably because some error in the code causes undefined behavior. Having the code then appear to "work" in the presence of a printf() is fine.
That indexing logic counting backwards looks scary; verify that it's correct. Print the index before using it, compare to the known size of the pathNodes array, if you have one. Beware of the index turning negative or overrunning the capacity of pathNodes.

Mysterious sprintf behavior in C: Second lld param prints as zero (0) always

I'm running into a downright bizarre issue with sprintf in C that seems beyond my basic abilities to debug. Basically, I'm using a simple unit test framework (CuTest) to add some tests to an ugly (undocumented, no unit tests) code base. I added a new type of unit test, which basically duplicates the ones that are already present- but for the 64 bit integers used in the code.
This test works in general (correctly evaluates equality comparisons), but when it fails it does not produce the correct error message due to the sprintf issue. The function looks like this:
/* Comparison Function for U64 Numbers */
void CuAssertU64Equals_LineMsg(CuTest* tc, const char* file, int line, const char* message, u64 expected, u64 actual) {
char buf[STRING_MAX];
if (expected == actual) return;
sprintf(buf, "expected <%lld> but was <%lld>", expected, actual);
CuFail_Line(tc, file, line, message, buf);
}
(Note: STRING_MAX is 512, so it should be plenty large).
(Note 2: On the Cygwin system I'm currently working with, a u64 is a "long long int" variable)
When this tests fails, the error message produced is the weird part. Regardless of what the value of "actual" is, it prints 0 in that spot. So given expected = 1 and actual = 2, the message would be:
"expected <1> but was <0>"
If you switch the positions of the arguments, and make it state something like:
sprintf(buf, "actually <%lld> but expected <%lld>", actual, expected);
You'd get the output:
"actually <2> but expected <0>"
Needless to say, this makes very little sense and seems to indicate some sort of weird stack error maybe? To be quite honest, I am just entirely unclear on how such an error could occur- even in principle. I made a small working example with the CuTest code and it worked properly (did not set the second one to zero). This indicates that the neither CuTest, nor the function itself is the issue.
However, when used with the actual code base it encounters this issue. Something related to the environment (stack, memory, or variables) is the issue.
Does anyone have a clue as to why this would happen? My current candidate theories are:
1. Underflow/overflow in the sprintf function when trying to read the data. I'm not sure how this would occur though, since any data passed into the function is by value. Moreover, the data itself clearly exists- I can see each value if I switch the order.
I'm using the incorrect formatting somehow. I was pretty sure lld was correct for a long long int (and works in my minimal working example) but maybe it's fragile.
Full on stack corruption of some sort. Sure hope its not this, because I'm only on this project 20 hours a week. I doubt I could debug the whole code base to figure out something of this magnitude.
I'm currently compiling using gcc-3 in a cygwin environment, for what it's worth. Any guesses would be great, I know it's basically impossible to diagnose it specifically without seeing the whole code base, but even some leads about debugging this sort of issue would be great.
Try "%I64d" as a format string instead. I'm not certain of Cygwin but I know MinGW links in the printf function from Visual Studio's standard library, causing all sorts of havoc. Beware of any new C99 features and types such as long doubles or size_t formats.
For what it's worth here's a replacement for printf in this context:
static char *CuPrintU64(char* buffer, u64 value) {
do
*--buffer = value % 10 + '0';
while(value /= 10);
return buffer;
}
/* Comparison Function for U64 Numbers */
void CuAssertU64Equals_LineMsg(CuTest* tc, const char* file, int line, const char* message, u64 expected, u64 actual) {
static const char first[] = "expected ";
static const char second[] = " but was ";
char buf[STRING_MAX], *ptr = &buf[sizeof buf];
if(expected == actual) return;
/* sprintf(buf, "expected <%llu> but was <%llu>", expected, actual); */
*--ptr = '\0';
ptr = CuPrintU64(ptr, actual);
ptr = memcpy(ptr - second, sizeof second - 1);
ptr = CuPrintU64(ptr, expected);
ptr = memcpy(ptr - first, sizeof first - 1);
CuFail_Line(tc, file, line, message, ptr);
}

Pointer becomes nothing for no apparent reason

Greetings!
I have a simple program in qt on c.
There are two pointers to type short, used to read from file and store bits from values read.
sample code:
//(input is a FILE* which is opened and passed to the function)
//(output is also a FILE* which is also opened and passed to the function)
//1. Variables declaration
short* sample_buffer;
int buffer_size=1;
short samples_read;
unsigned long value_x=7;
short* nzb_buffer;
short buffer_position=-1;
int i;
//2.Memory allocation
sample_buffer= malloc(sizeof(short)*buffer_size);
nzb_buffer = malloc(sizeof(short)*value_x);
....
//3. Read from infile, one short at time, process and write it to outfile
do
{
//3.1. Read from input file
samples_read = fread(sample_buffer,sizeof(short),buffer_size, input);
//3.2. Switch position inside nzb_buffer one to the right,
// going back to zero if out of bounds
buffer_position=(buffer_position+1)%value_x;
....
//3.3. Put least significant bit of the just read short into nzb_buffer
nzb_buffer[buffer_position]=sample_buffer[0]%2;
....
//3.4. Write the short we just read from infile to the outfile
for (i=0;i<samples_read;i++)
{
fwrite(sample_buffer,sizeof(short),1, output);
}
} while(samples_read==buffer_size);
I've let unreliant pieces of code out. If you need to see something else please tell me.
Problem is, after like 10 or 15 operations of the loop, it crashes with "Segmentation fault" signal. It crashes on the fwrite() function.
I debugged and i use watch on sample_buffer. For some reason, on one exact step, the operation nzb_buffer[buffer_position]=sample_buffer[0]%2 makes sample_buffer become 0x0 (i belive, it becomes a null pointer).
This cannot be overflowing on nzb_buffer because buffer_position for that operation is 3 (out of 7 allocated for the particular array in malloc). And since each loop makes one write operation and shifts the carry, the operation of writing into nzb_buffer[3] has already happened before in the loop and did not nullify the pointer that time.
I am totally clueless what may be happening here.
Anybody has any ideas what is going on or how do i debug it?
Thanks in advance!
PS: Added comments "what the code does"
Your exit condition for the loop seems to be misplaced. I would do:
samples_read = fread(sample_buffer,sizeof(short),buffer_size, input);
while(samples_read==buffer_size){
[...]
samples_read = fread(sample_buffer,sizeof(short),buffer_size, input);
}

Resources