Page 1 of 2

Debugging code that shows no errors...

Posted: Mon Feb 18, 2013 3:49 am
by Belxjander
I currently have a quandary as I have a section of code that appears to complete normally yet actively fails to operate...

If anyone can please look at http://polymorph.googlecode.com/svn/Pol ... y/daemon.c

And explain where I am going wrong with trying to make a commodity presence please?

Re: Debugging code that shows no errors...

Posted: Mon Feb 18, 2013 11:26 am
by tonyw
What do you mean by "fails to operate"? Does it crash? Or does it simply exit without doing anything?

A couple of things that stand out:

1. You haven't tested the success of any of the Interface opens. If you proceed to handle events with null interface pointers, it's going to crash.
2. You are depending on an OS4 environment, yet you are checking only for V40 libraries. They ought to be V53.
3. There isn't a _start function anywhere. Is it somewhere else? Are you building with -mcrt=newlib or clib?

You don't seem to have any debug code in there (or have you merely removed it for the post?). I would start with an IExec->DebugPrintF() after every line of code until you are sure about the code up to a certain point - then you can edit out the debug calls up until that point.

You didn't show your makefile, but I hope you are compiling each module with -gstabs. That way you generate a symbol table in the binary and can use the "addr2line" command to find out where crashes are from the stack trace.

Re: Debugging code that shows no errors, crashes or other ac

Posted: Mon Feb 18, 2013 1:19 pm
by Belxjander
tonyw wrote:What do you mean by "fails to operate"? Does it crash? Or does it simply exit without doing anything?

A couple of things that stand out:

1. You haven't tested the success of any of the Interface opens. If you proceed to handle events with null interface pointers, it's going to crash.
see the "InitCommodity()" and "InitRegistration()" function contents at the bottom...

the Assumption that I don't test any of the Interface pointers is of itself a bit premature here...
tonyw wrote: 2. You are depending on an OS4 environment, yet you are checking only for V40 libraries. They ought to be V53.
3. There isn't a _start function anywhere. Is it somewhere else? Are you building with -mcrt=newlib or clib?
I am building a shared library and this is only a single file (the rest of the library and GNUmakefile are in the same location...)
check it out and try to "make" in any given folder of the entire project...the "-mcrt=newlib" is declared in the GNUmakefile
tonyw wrote: You don't seem to have any debug code in there (or have you merely removed it for the post?). I would start with an IExec->DebugPrintF() after every line of code until you are sure about the code up to a certain point - then you can edit out the debug calls up until that point.
No awareness of how to "see" the results of those debugging calls... and I currently operate only a single machine...
nothing connected to any form of "serial link" and that is the total sum of knowledge about the Exec DebugPrintF() results that I know...so there has never been any Exec debugging calls at this time.

I don't even know where to SEE the results of DebugPrintF() calls (the code has been "blind-written" for the target system with minimal testing so far)
tonyw wrote: You didn't show your makefile, but I hope you are compiling each module with -gstabs. That way you generate a symbol table in the binary and can use the "addr2line" command to find out where crashes are from the stack trace.
[/quote]
Does this also apply when the "application" in question is launched from inside a Shared Library (.library native, not the .so imported material) as there is no "executable image" that stands alone...

However primarily, I am seeing "no errors, failures, crashes or other misbehaviour" additionally I am not seeing the creation or presence of my "Polymorph-VMM" daemon process in anything but the DOS->Processes listing of Ranger...

Exchange and AMIdock both fail to display any presence awareness in the Graphical UI they show when run,
This is the desired result and I don't see it.

Any assumption that this "program" is becoming a stand alone commodity are actually entirely false,

I have a Shared Library which contains an internal daemon (this is the part which needs to show as a commodity)
as I am specifically having the daemon "server" certain materials once I can seperate the plugins into "client" and "server" API sections.

at this time the core library framework will appear sparse compared to what it will actually contain.

I had the impression that AmigaOS developers were not needing to be "spoonfed" all the details and would actively look around a bit more...

Re: Debugging code that shows no errors...

Posted: Mon Feb 18, 2013 7:07 pm
by Karlos
Belxjander wrote:No awareness of how to "see" the results of those debugging calls... and I currently operate only a single machine...
nothing connected to any form of "serial link" and that is the total sum of knowledge about the Exec DebugPrintF() results that I know...so there has never been any Exec debugging calls at this time.

I don't even know where to SEE the results of DebugPrintF() calls (the code has been "blind-written" for the target system with minimal testing so far)
Try the C:DumpDebugBuffer command if you don't have anything attached to the serial port or any serial -> file redirection.

Re: Debugging code that shows no errors, crashes or other ac

Posted: Mon Feb 18, 2013 7:32 pm
by LyleHaze
Belxjander wrote:
tonyw wrote:What do you mean by "fails to operate"? Does it crash? Or does it simply exit without doing anything?

A couple of things that stand out:

1. You haven't tested the success of any of the Interface opens. If you proceed to handle events with null interface pointers, it's going to crash.
see the "InitCommodity()" and "InitRegistration()" function contents at the bottom...

the Assumption that I don't test any of the Interface pointers is of itself a bit premature here...
[/quote]

I checked InitCommodity, and found the following code:

Code: Select all

	if((Self->CxBase!=NULL)&&(Self->ICX!=NULL))
	{
		Self->cxHandle=Self->ICX->CxBroker(&dcxinit,&error);
		if(Self->cxHandle!=NULL)
		{
			Self->ICX->ActivateCxObj(Self->cxHandle, active);
		}
	}
	return;
So what happens if Self->ICX is NULL??
You will never call ActivateCXObj, and never alert the user that it was not called.
This would give a result of failing without warning or reason, leaving the user completely uninformed as to why it doesn't work.
As I recall, that is exactly the problem you are asking for help with.

MOST of other interface pointers you are "maybe initializing", (IUtility, ILocale, IDataTypes, and IApplication) are not checked
for a valid return anywhere in the code you provided.

However, IDOS _IS_ being used without any check to verify that it is non_Null.. in your call to CreateNewProcTags().
If your open of DOS library or GetInterface fail for any reason, your code will crash and burn at this point.

This makes a good explanation of why MOST programmers check for valid results of opens before proceeding, instead of
testing them later at each usage, like was done with your CxBroker call. And it might be helpful to actually inform the user
of why an open failed, or at least IF there was a failure, instead of just "skipping over" those calls that don't have a valid
resource available.
Belxjander wrote: I had the impression that AmigaOS developers were not needing to be "spoonfed" all the details and would actively look around a bit more...
You might get better advice here if you try to avoid insulting those who have taken the time to help you.
Tony's advice is right on target, your comment shows a problem with your attitude.

Re: Debugging code that shows no errors...

Posted: Mon Feb 18, 2013 9:44 pm
by blmara
@all

About using DebugPrintF(); I would certainly recommend Sashimi (http://os4depot.net/share/development/debug/sashimi.lha) to easily and in real time see the output of DebugPrintF()! No need for another computer or cables.

Marko

Re: Debugging code that shows no errors, crashes or other ac

Posted: Wed Feb 20, 2013 12:36 am
by Belxjander
LyleHaze wrote:
Belxjander wrote:
tonyw wrote:What do you mean by "fails to operate"? Does it crash? Or does it simply exit without doing anything?

A couple of things that stand out:

1. You haven't tested the success of any of the Interface opens. If you proceed to handle events with null interface pointers, it's going to crash.
see the "InitCommodity()" and "InitRegistration()" function contents at the bottom...

the Assumption that I don't test any of the Interface pointers is of itself a bit premature here...
I checked InitCommodity, and found the following code:

Code: Select all

	if((Self->CxBase!=NULL)&&(Self->ICX!=NULL))
	{
		Self->cxHandle=Self->ICX->CxBroker(&dcxinit,&error);
		if(Self->cxHandle!=NULL)
		{
			Self->ICX->ActivateCxObj(Self->cxHandle, active);
		}
	}
	return;
So what happens if Self->ICX is NULL??
You will never call ActivateCXObj, and never alert the user that it was not called.
This would give a result of failing without warning or reason, leaving the user completely uninformed as to why it doesn't work.
As I recall, that is exactly the problem you are asking for help with.

MOST of other interface pointers you are "maybe initializing", (IUtility, ILocale, IDataTypes, and IApplication) are not checked
for a valid return anywhere in the code you provided.

However, IDOS _IS_ being used without any check to verify that it is non_Null.. in your call to CreateNewProcTags().
If your open of DOS library or GetInterface fail for any reason, your code will crash and burn at this point.

This makes a good explanation of why MOST programmers check for valid results of opens before proceeding, instead of
testing them later at each usage, like was done with your CxBroker call. And it might be helpful to actually inform the user
of why an open failed, or at least IF there was a failure, instead of just "skipping over" those calls that don't have a valid
resource available.
Belxjander wrote: I had the impression that AmigaOS developers were not needing to be "spoonfed" all the details and would actively look around a bit more...
You might get better advice here if you try to avoid insulting those who have taken the time to help you.
Tony's advice is right on target, your comment shows a problem with your attitude.[/quote]

Well, my "attitude" is based on being ignored when I am being "nice",
Being blunt seems to be the only time I get any response at all.

as for the "advice", I have had too many "well intentioned" individuals "advise" me to in effect "f*** off", online and offline.

Thank you for pointing out that I had missed a check, I've now fixed that and will be pushing that up to the repo along with a few other changes.

the current scheme of testing is not the first iteration (where everything was attempted regardless) and the testing for "if(x)" that has been put in has made no apparent change at all.

Re: Debugging code that shows no errors...

Posted: Wed Feb 20, 2013 1:16 am
by ssolie
Play nice boys... no need to get personal. You can be "blunt" without being insulting.

Thanks.

Re: Debugging code that shows no errors...

Posted: Wed Feb 20, 2013 11:12 pm
by tonyw
The current scheme of testing is not the first iteration (where everything was attempted regardless) and the testing for "if(x)" that has been put in has made no apparent change at all.
I didn't expect it would. It would only have prevented a crash, anyway.

I think you just don't have enough information about what your program is doing. It's very difficult for someone else to point out failings unless they are glaringly obvious, and none of us can see anything like that.

I say again, I suggest that you add copious debug output that at least will tell you what it is doing, where it is going and so on. It only needs to be there for a few days until you get it working, then you can switch it off.

If you haven't used DebugPrintF() before, it writes its output (using HW wait loops) directly to the serial port, or, if Sashimi is running, to a file. If you don't have a console that you can printf() to, then DebugPrintF() is your only recourse. You can of course open and write to a file, but that risks not being able to close the file when you have a crash. The kernel writes the debug output to a debug buffer in memory if "serial" is not included in the command string (I think, perhaps someone else can correct me there). You can later dump that using the command "DumpDebugBuffer", but that is of little use to you if the system has crashed.

I rely on a second machine, connected to a terminal emulator via serial. It's the way I've worked for years, since I've only ever worked on low-level drivers, etc.

I use a macro like this (in the debug header):

#define kprintf(format, args...)((struct ExecIFace *) \
((*(struct ExecBase **)4)->MainInterface))->DebugPrintF(format, ## args)

then I simply call kprintf () in the code. It doesn't depend on any other variables, it's as slow as a wet week, but it is reliable. Remember that all args are pushed onto the stack as 32-bit values, so you have to use 32-bit format fields, eg "%lc" for a character and "%ld" for a 16-bit number. Also, if you want to print 64-bit values, they must be pushed onto the stack properly aligned, so:
kprintf ("At line %ld, address is %lld\n", __LINE__, address) won't work, the 64-bit value is misaligned. You have to say:
kprintf ("At line %lld, address is %lld\n", (int64)__LINE__, address) or make sure you have an even number of 32-bit values before the 64-bit value.

Once you've got some output, your problem might be clear to you. It's getting the debug capture set up that takes time. Once you've done it, it's simplicity itself to add another kprintf() call at a suspicious place.

Good luck.

Re: Debugging code that shows no errors...

Posted: Fri Feb 22, 2013 10:43 am
by trixie
@belxjander

Like others, I can heartily recommend using Sashimi for debug output.

When I start a project I always execute MemGuard and Sashimi to run throughout the coding session. This way I can see my own debug output as well as trace any memory-related problems I'm causing by my lousy programming :-)