EmbeddedRelated.com
Forums

dynamic c debugging

Started by "weeeedy.1337" October 5, 2010
currently i am getting a "Index out of bounds" runtime error when i run one of my programs. also the message give a code line number but this is certainly incorrect, since the code at that location is never ever able to be called.

so i have a problem that i have a error, but have no idea where it is.
the program is very big and very complex. i have tried to put debugging print statements around the place to hopefully find the location that this error occurs, but multi tasking does not make things easier. and my printf's havent helped anything yet.

is any experienced enough here to know of practical ways to find my problem, or to get the compiler to report the correct location?

This usually means you are writing beyond an array somewhere. Check all your array sizes and make sure no code is trying to write beyond them.

example

char Text[20];

text[20] = 'A';

The above line will fail as the array is only from 0-19. The 20 element is out of bounds.

Dave...
---
Very funny Scotty, now beam down my clothes!!
---
http://www.embeddedcomputer.co.uk
---

----- Original Message -----
From: weeeedy.1337
To: r...
Sent: Tuesday, October 05, 2010 2:51 PM
Subject: [rabbit-semi] dynamic c debugging

currently i am getting a "Index out of bounds" runtime error when i run one of my programs. also the message give a code line number but this is certainly incorrect, since the code at that location is never ever able to be called.

so i have a problem that i have a error, but have no idea where it is.
the program is very big and very complex. i have tried to put debugging print statements around the place to hopefully find the location that this error occurs, but multi tasking does not make things easier. and my printf's havent helped anything yet.

is any experienced enough here to know of practical ways to find my problem, or to get the compiler to report the correct location?
Lawrence,

This type of error usually occurrs due to memory corruption due to pointer overruns or other issues when copying data so the areas to concentrate on are usually around the copying of data and checking that the correct addresses and data lengths are used.

Having said that, there are a number of other things that have contributed to similar issues when I have been working on the code for the BACnet stack (http://sourceforge.net/projects/bacrabbit/) that were due to compiler issues or limitations:

1. Dynamic C will let you declare far arrays that exceed the documented 32K limit without raising an error and will generate incorrect code which can lead to overwriting of the wrong memory. I came across this when developing the Trend Log object which uses big arrays. I now define the arrays as normal and use explicit far pointer calculations to read and write them.

2. The following example generates incorrect code for the references to MyData if it is in a lib file but not if it is in main.c:

/*** BeginHeader MyData */
typedef struct MyData {
char cMyByte1;
char cMyByte2;
float fMyReal;
char sMyString[30];
} DATABLOCK;

extern far DATABLOCK MyData[10];
/*** EndHeader */
far DATABLOCK MyData[10];

/*** BeginHeader MyDatax */
typedef struct mydatax {
char cMyByte1;
char cMyByte2;
float fMyReal;
char sMyString[30];
} DATABLOCKX;

extern far DATABLOCKX MyDatax[10];
/*** EndHeader */
far DATABLOCKX MyDatax[10];

/*** BeginHeader testx */
testx();
/*** EndHeader */
testx()

{
_f_strncpy(MyData[1].sMyString, "test", 4);
_f_strncpy(MyDatax[1].sMyString, "test", 4);
}

i.e. It seems
that in a library you can't have a structure type name the same as a
variable but you can in
the main code i.e. .

typedef struct MyData {
...
} DATABLOCK;

far DATABLOCK MyData[10];

fails (MyData used in both cases) but

typedef struct mydatax {
...
} DATABLOCKX;

far DATABLOCKX MyDatax[10];

works because mydatax and MyDatax are different.

3. I've come across a problem when using a pointer to a function where compiler produces incorrect code ( I noticed it because the function being called returns a bool to indicate success or failure but even when I knew it should have failed the code always took the successful path).

The original code which fails is:

if (pObject->Object_Valid_Instance && pObject->Object_Valid_Instance(rpdata->object_instance)) {

Rewriting the code slightly differently as (which should be equivelant):

if ((pObject->Object_Valid_Instance != 0) &&
(pObject->Object_Valid_Instance(rpdata->object_instance) != 0)) {

produces the correct code

Regards,
Peter

--- In r..., "weeeedy.1337" wrote:
>
> currently i am getting a "Index out of bounds" runtime error when i run one of my programs. also the message give a code line number but this is certainly incorrect, since the code at that location is never ever able to be called.
>
> so i have a problem that i have a error, but have no idea where it is.
> the program is very big and very complex. i have tried to put debugging print statements around the place to hopefully find the location that this error occurs, but multi tasking does not make things easier. and my printf's havent helped anything yet.
>
> is any experienced enough here to know of practical ways to find my problem, or to get the compiler to report the correct location?
>

Op Oct 5, 2010, om 9:51 AM heeft weeeedy.1337 het volgende geschreven:

> currently i am getting a "Index out of bounds" runtime error when i
> run one of my programs. also the message give a code line number
> but this is certainly incorrect, since the code at that location is
> never ever able to be called.

In that case this will be caused by some sort of memory corruption,
but one that happens prior to the actual error condition so it may
not have anything to do with arrays at all. What's happening here is
that either program execution really jumped to this piece of code
that shouldn't normally be called, or that some uncaught error
condition causes this error and the line number is just garbage (and
happens to point to a piece of code).

Stack overflows and too complex cofunction/costate constructions, can
sometimes lead to program execution jumping around the place. The
only way to find this out is by stepping through your program until
this error occurs, in a few passes (first use step all the time until
it happens, then use 'step into' when you know you're getting close
to the problem). At some point sooner or later you should find a
point in your program where you're doing something bad, or you'll see
the program counter jumping to a totally wrong location after
returning from a function. In that last case, you have a stack overflow.

Hope this helps - my experience with these cases is, sometimes you're
lucky, sometimes you'll loose days :)

Maurits.

>Stack overflows and too complex cofunction/costate constructions, can
> sometimes lead to program execution jumping around the place. The
> only way to find this out is by stepping through your program until
> this error occurs, in a few passes (first use step all the time until
> it happens, then use 'step into' when you know you're getting close
> to the problem). At some point sooner or later you should find a
> point in your program where you're doing something bad, or you'll see
> the program counter jumping to a totally wrong location after
> returning from a function. In that last case, you have a stack overflow.

The complexity of my program does not make single stepping convenient,
especially when the error occurs at random times that I cant determine,
sometimes a minute after boot, sometimes ten minutes. I have attempted
something daring, I turned on tracing, since it was the only way I could see
fit to within time constraints hopefully find the culprit. This grinds
execution to a snails pace, but behold half an hour later, a trace log
revealed what function contained the faulting code. The error was merely a
maximum length that was not initialized.

Fine that I have found the culprit. But still. Why does the runtime and the
compiler give me the wrong location?

> Hope this helps - my experience with these cases is, sometimes you're
lucky, sometimes you'll loose days :)

This is truth.
> Fine that I have found the culprit. But still. Why does the runtime
> and the compiler give me the wrong location?
>
Runtime errors have to be calculated back to line numbers afterwards
by the debugger, and it's possible that the actual memory corruption
messed this up.

Maurits.
I think it's also possible that the error message is correct - and that the program did fault at that location, but it faulted because of memory corruption which occured elsewhere.

-Kenny

--- In r..., Maurits van de Kamp wrote:
> > Fine that I have found the culprit. But still. Why does the runtime
> > and the compiler give me the wrong location?
> >
> Runtime errors have to be calculated back to line numbers afterwards
> by the debugger, and it's possible that the actual memory corruption
> messed this up.
>
> Maurits.
>

I think that there were some versions of Dynamic C 10 that weren't reporting the correct address for runtime errors. The ChangeLog for 10.62 included this entry:
- Defect #21625. Run-time exceptions did not always show the
correct line and file information. Run-time exceptions now
display the file, function, and line information when available,
and the address of the exception otherwise.
So if you're using a version of DC 10 before the 10.62 release, that could be the reason.

I know that the DC 9 releases earned a reputation whereby many people avoided updating from the 9.21 to 9.52 releases (the 9.62 release seemed to be OK). With DC 10, I feel like each release is consistently better than the last.

-Tom
On Oct 5, 2010, at 5:06 AM, Lawrence Ward wrote:
> Fine that I have found the culprit. But still. Why does the runtime and the compiler give me the wrong location?