BUS Error after Execute statement
Posted in 2000
Topics: Connectivity: ESQL/C, 4GL & Embedded SQL
Dear all, I'm trying to drop 416 columns from one single table using the esql's PREPARE and EXECUTE statement. This does not seems working for me, I had the core dump, "bus error" run-time error. I wondering whether this is cause by my long esql statement which exceeded the buffer limit. Please advise. This is how i code my esql statements: sprintf(alterStr,"ALTER table mdmmotable DROP ("); for-loop ..... sprintf(columnStr, "spanatsi%d", i); sprintf(tempstr,","); strcat(alterStr, tempstr); ..... sprintf(tempstr, " %s", columnStr); strcat(alterStr, tempstr); end-for ..... $PREPARE alterMDMCol from $alterStr; $EXECUTE alterMDMCol; Regads kit
"Kit Ming, Low" wrote: > I'm trying to drop 416 columns from one single table using the esql's > PREPARE and EXECUTE statement. This does not seems working for me, I > had the core dump, "bus error" run-time error. I wondering whether this > is cause by my long esql statement which exceeded the buffer limit. > Please advise. Yes; it is a classic symptom of extreme buffer overflow. Did you measure the length of the result string and compare it with the declared length of the string? > This is how i code my esql statements: > sprintf(alterStr,"ALTER table mdmmotable DROP ("); > for-loop > ..... > sprintf(columnStr, "spanatsi%d", i); > sprintf(tempstr,","); > strcat(alterStr, tempstr); > ..... > sprintf(tempstr, " %s", columnStr); > strcat(alterStr, tempstr); > end-for > ..... > $PREPARE alterMDMCol from $alterStr; > $EXECUTE alterMDMCol; -- Yours, Jonathan Leffler (Jonathan.Leffler@Informix.com) #include <disclaimer.h> Guardian of DBD::Informix v1.00.PC1 -- http://www.perl.com/CPAN "I don't suffer from insanity; I enjoy every minute of it!"
Yes. The declared length of the string is large enough to store the result string. Any pointer for me to resolve this classic symptom. The only method is to break down the statement into few sub-sql statements, but this will have performance trade-off. Regards kitming p/s: thank you, Jonanthan :P Jonathan Leffler wrote: > "Kit Ming, Low" wrote: > > > I'm trying to drop 416 columns from one single table using the esql's > > PREPARE and EXECUTE statement. This does not seems working for me, I > > had the core dump, "bus error" run-time error. I wondering whether this > > is cause by my long esql statement which exceeded the buffer limit. > > Please advise. > > Yes; it is a classic symptom of extreme buffer overflow. > > Did you measure the length of the result string and compare it > with the declared length of the string? > > > This is how i code my esql statements: > > sprintf(alterStr,"ALTER table mdmmotable DROP ("); > > for-loop > > ..... > > sprintf(columnStr, "spanatsi%d", i); > > sprintf(tempstr,","); > > strcat(alterStr, tempstr); > > ..... > > sprintf(tempstr, " %s", columnStr); > > strcat(alterStr, tempstr); > > end-for > > ..... > > $PREPARE alterMDMCol from $alterStr; > > $EXECUTE alterMDMCol; > > -- > Yours, > Jonathan Leffler (Jonathan.Leffler@Informix.com) #include <disclaimer.h> > Guardian of DBD::Informix v1.00.PC1 -- http://www.perl.com/CPAN > "I don't suffer from insanity; I enjoy every minute of it!"
On Thu, 12 Oct 2000, Kit Ming, Low wrote:
>Yes. The declared length of the string is large enough to store the result
>string.
OK; you don't provide any evidence to backup that assertion, but as long
as your declaration for alterStr is more than 5329 characters long, and
the tempstr and columnStr are more than about 16 characters, you are
correct. You would be more convincing if you showed your code, of
course.
>Any pointer for me to resolve this classic symptom. The only method is
>to break down the statement into few sub-sql statements, but this will
>have performance trade-off.
I took the skeleton you supplied and converted it into a pure C program:
#include <string.h>
#include <stdio.h>
int main()
{
int i;
char columnStr[256];
char tempstr[256];
char alterStr[65536];
sprintf(alterStr,"ALTER table mdmmotable DROP (");
for (i = 0; i < 416; i++)
{
sprintf(columnStr, "spanatsi%d", i);
sprintf(tempstr,",");
strcat(alterStr, tempstr);
sprintf(tempstr, " %s", columnStr);
strcat(alterStr, tempstr);
}
strcat(alterStr, ")");
printf("Len = %u\\n", strlen(alterStr));
puts(alterStr);
return(0);
}
I added the close parenthesis strcat(), but the generated output from
the program is two lines (I've severely truncated the second line and
split it over two lines):
Len = 5328
ALTER table mdmmotable DROP (, spanatsi0, spanatsi1, spanatsi2, ...
spanatsi413, spanatsi414, spanatsi415)
Note that stray, unwanted ", " after the open parenthesis. I take it
that you have not looked at the generated string; if you had, your code
would deal with it. Did you actually use strlen() on the string to
check how big it was?
The way I'd deal with the loop you wrote is:
#include <string.h>
#include <stdio.h>
int main()
{
int i;
char *pad;
char alterStr[65536];
char *end;
end = alterStr;
pad = "ALTER table mdmmotable DROP (";
for (i = 0; i < 416; i++)
{
sprintf(end, "%sspanatsi%d", pad, i);
end += strlen(end);
pad = ", ";
}
strcat(end, ")");
printf("Len = %u\\n", strlen(alterStr));
puts(alterStr);
return(0);
}
In this case, I have a big string as the initial padding; often, the
initial value of pad is an empty string.
Now, where do you get the bus error? Do you know which part of the
code you showed actually generated the bus error? If not, you need
to find out. If, as you say, there is no problem with the size of
the arrays, then I suspect that the three sets of dots in your code
outline may be causing the damage.
>Jonathan Leffler wrote:
>> "Kit Ming, Low" wrote:
>> > I'm trying to drop 416 columns from one single table using the esql's
>> > PREPARE and EXECUTE statement. This does not seems working for me, I
>> > had the core dump, "bus error" run-time error. I wondering whether this
>> > is cause by my long esql statement which exceeded the buffer limit.
>> > Please advise.
>>
>> Yes; it is a classic symptom of extreme buffer overflow.
>>
>> Did you measure the length of the result string and compare it
>> with the declared length of the string?
>>
>> > This is how i code my esql statements:
>> > sprintf(alterStr,"ALTER table mdmmotable DROP (");
>> > for-loop
>> > .....
>> > sprintf(columnStr, "spanatsi%d", i);
>> > sprintf(tempstr,",");
>> > strcat(alterStr, tempstr);
>> > .....
>> > sprintf(tempstr, " %s", columnStr);
>> > strcat(alterStr, tempstr);
>> > end-for
>> > .....
>> > $PREPARE alterMDMCol from $alterStr;
>> > $EXECUTE alterMDMCol;
--
Yours,
Jonathan Leffler (Jonathan.Leffler@Informix.com) #include <disclaimer.h>
Guardian of DBD::Informix v1.00.PC1 -- http://www.perl.com/CPAN
"I don't suffer from insanity; I enjoy every minute of it!"
Jonathan,
Sorry for my late replying and would like to thank you for helping looking into
the matter. This week was hectic and busiest week in my life. :P
Actually, this problem was reported by one of my colleague which i would like to
trace the code as well and find out the root cause. I will find some time to
figure out the problem. May be somewhere next week. Will copy you my finding
though.
Best regards
kitming
Jonathan Leffler wrote:
> On Thu, 12 Oct 2000, Kit Ming, Low wrote:
> >Yes. The declared length of the string is large enough to store the result
> >string.
>
> OK; you don't provide any evidence to backup that assertion, but as long
> as your declaration for alterStr is more than 5329 characters long, and
> the tempstr and columnStr are more than about 16 characters, you are
> correct. You would be more convincing if you showed your code, of
> course.
>
> >Any pointer for me to resolve this classic symptom. The only method is
> >to break down the statement into few sub-sql statements, but this will
> >have performance trade-off.
>
> I took the skeleton you supplied and converted it into a pure C program:
>
> #include <string.h>
> #include <stdio.h>
>
> int main()
> {
> int i;
> char columnStr[256];
> char tempstr[256];
> char alterStr[65536];
>
> sprintf(alterStr,"ALTER table mdmmotable DROP (");
> for (i = 0; i < 416; i++)
> {
> sprintf(columnStr, "spanatsi%d", i);
> sprintf(tempstr,",");
> strcat(alterStr, tempstr);
> sprintf(tempstr, " %s", columnStr);
> strcat(alterStr, tempstr);
> }
> strcat(alterStr, ")");
> printf("Len = %u\\n", strlen(alterStr));
> puts(alterStr);
> return(0);
> }
>
> I added the close parenthesis strcat(), but the generated output from
> the program is two lines (I've severely truncated the second line and
> split it over two lines):
>
> Len = 5328
> ALTER table mdmmotable DROP (, spanatsi0, spanatsi1, spanatsi2, ...
> spanatsi413, spanatsi414, spanatsi415)>
> Note that stray, unwanted ", " after the open parenthesis. I take it
> that you have not looked at the generated string; if you had, your code
> would deal with it. Did you actually use strlen() on the string to
> check how big it was?
>
> The way I'd deal with the loop you wrote is:
>
> #include <string.h>
> #include <stdio.h>
>
> int main()
> {
> int i;
> char *pad;
> char alterStr[65536];
> char *end;
>
> end = alterStr;
> pad = "ALTER table mdmmotable DROP (";
> for (i = 0; i < 416; i++)
> {
> sprintf(end, "%sspanatsi%d", pad, i);
> end += strlen(end);
> pad = ", ";
> }
> strcat(end, ")");
> printf("Len = %u\\n", strlen(alterStr));
> puts(alterStr);
> return(0);
> }
>
> In this case, I have a big string as the initial padding; often, the
> initial value of pad is an empty string.
>
> Now, where do you get the bus error? Do you know which part of the
> code you showed actually generated the bus error? If not, you need
> to find out. If, as you say, there is no problem with the size of
> the arrays, then I suspect that the three sets of dots in your code
> outline may be causing the damage.
>
> >Jonathan Leffler wrote:
> >> "Kit Ming, Low" wrote:
> >> > I'm trying to drop 416 columns from one single table using the esql's
> >> > PREPARE and EXECUTE statement. This does not seems working for me, I
> >> > had the core dump, "bus error" run-time error. I wondering whether this
> >> > is cause by my long esql statement which exceeded the buffer limit.
> >> > Please advise.
> >>
> >> Yes; it is a classic symptom of extreme buffer overflow.
> >>
> >> Did you measure the length of the result string and compare it
> >> with the declared length of the string?
> >>
> >> > This is how i code my esql statements:
> >> > sprintf(alterStr,"ALTER table mdmmotable DROP (");
> >> > for-loop
> >> > .....
> >> > sprintf(columnStr, "spanatsi%d", i);
> >> > sprintf(tempstr,",");
> >> > strcat(alterStr, tempstr);
> >> > .....
> >> > sprintf(tempstr, " %s", columnStr);
> >> > strcat(alterStr, tempstr);
> >> > end-for
> >> > .....
> >> > $PREPARE alterMDMCol from $alterStr;
> >> > $EXECUTE alterMDMCol;
>
> --
> Yours,
> Jonathan Leffler (Jonathan.Leffler@Informix.com) #include <disclaimer.h>
> Guardian of DBD::Informix v1.00.PC1 -- http://www.perl.com/CPAN
> "I don't suffer from insanity; I enjoy every minute of it!"