Re: Partial string loss with sprintf/strcat
- From: Neal Barney <joeno99@xxxxxxxxxxx>
- Date: Thu, 03 Aug 2006 11:35:15 -0600
On Mon, 31 Jul 2006 05:11:18 +0000, Dave Thompson wrote:
Like other responders I don't see any likely culprits in the partial
code you posted. As already suggested collecting information about the
state and sequence(s) leading up to a fault is likely to be helpful in
narrowing down the suspects, and/or helping you construct cases that
will reproduce it in test. I realize general advice like this is not
much more helpful than telling you that candy tastes good.
Well, I suppose it is a small comfort to me that I'm not crazy and didn't
overlook something patently obvious. After further research I do believe
that I have a better idea of what is going on. The stack and heap size
must be pre-declared and it appears as if the declared stack size is too
small. The stack space is being exceeded (or so it appears). I have
given the stack an additional 1000 bytes and will do further testing to
see if this resolves the issue. If it doesn't I'm in trouble. :-) With
that change to the stack size that puts my memory usage at 16302 bytes out
of 16384. Talk about pushing the limits... :-O
It may be obvious, but if you haven't done so already I would inspect
the generated (and I assume shipped) assembler/machine code for your
routine and if reasonably possible (and not prohibited) for the library
routines your code calls (sprintf, strcat, etc.) just to make sure the
compiler/implementor isn't doing something dumb somewhere. (But that
part would be offtopic for c.l.c, except maybe for questions about
exactly what standard-library routines are required to do, especially in
corner cases, which I don't see you approaching.)
A good suggestion but it's been years since I inspected assembler level
code. And this machine uses a modified variant of the "Amsterdam
compiler" that compiles to EM byte-code. The machine runs an interpreter
that translates the EM code to native machine calls. I suppose there may
be enough information out there to learn more about the EM byte code and
figure things out, but that will probably be a last resort.
I do however see something I would do differently in a memory
constrained environment (and maybe even a normal one) which might or
might not be of help to you. Instead of building the message body in one
buffer (tmpMsg) and then copying it plus a small fixed-length prefix
into another (Message), do something like:
size_t used = sprintf (&Message[4], "format", headerargs); strcpy
(&Message[4+used], nextitem); used += nextitemlen; etc., bumping used
in the process as long as not too difficult char tmpLen [4+1]; sprintf
(tmpLen, "%04d", used /* or strlen (Message+4) */ ); memcpy
(&Message[0], tmpLen, 4);
/* you can simplify &Message[n] to Message+n and particularly
&Message[0] to Message if your compiler is so badly lame it doesn't */
I already rewrote the function to do exactly what you are suggesting
(though implemented a little differently). It should now be more
efficient as well as likely being easier to see which call is causing me
the issue. We'll see if this makes a difference.
If the code generated, by your compiler for your target*, to access
(within) the global/static buffer is less efficient, use a pointer into
it instead:
/* register? */ char * putMsg = &Message[4]; putMsg += sprintf
(putMsg, "format", headerargs); etc.
(* For 8080 and IIRC Z80, linker-resolved globals or statics are
actually better, but I don't know if Z180 is different here.)
Also, if you have snprintf (or _snprintf or somesuch) available in your
library, you might use that instead. (It is standard in C99 for hosted
environments, but I'd guess the implementation you're using isn't even
trying to conform at that level.) For the code and data you posted it
doesn't look likely that you're overflowing, but it could be arbitrarily
bad if you do, so if you can be certain at reasonable cost you don't
it's probably worth it just to rule that out.
I do not have a snprintf of any sort available to me. The compiler I'm
using is ANSI C89 conforming, but that's as far as it goes (The compiler
was written in 1993). I thought about using a third party library (such
as trio), but in the end I decided that it wasn't worth linking against
any additional code. Size is too important when the program gets
downloaded at 2400/1200baud.
I appreciate all of the replies I have received. I apologize for asking
the question and then more-or-less disappearing. I was out of town on
training and didn't have Usenet access. But all of the suggestions have
been much appreciated.
.
- References:
- Re: Partial string loss with sprintf/strcat
- From: Dave Thompson
- Re: Partial string loss with sprintf/strcat
- Prev by Date: Re: writing to a text file line by line
- Next by Date: Re: anyone interested in decompilation
- Previous by thread: Re: Partial string loss with sprintf/strcat
- Next by thread: Re: Casting a byte array to allow assignment
- Index(es):
Relevant Pages
|