Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to "verify" your details, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ Programming ➜ General ➜ problems with edit_buffer()

problems with edit_buffer()

It is now over 60 days since the last post. This thread is closed.     Refresh page


Posted by Terry   USA  (87 posts)  Bio
Date Sat 03 Jan 2009 07:11 PM (UTC)

Amended on Sat 03 Jan 2009 07:38 PM (UTC) by Terry

Message
A few of my builders have said the format feature in the editor would be much better if it had a way of providing a hanging indent, so I tried to do it. This is the SWRFUSS codebase.
// handler.c
char *strlinwrp( char *src, int length, int indent )
{
   int wrdlen, marker = 0;
   char newstr[MSL], word[MSL];

   // indents = repeat_string( indent, " " );
   char indents[MSL], token[MSL];
   if( indent ) {
      sprintf( token, "%%%ds", indent );
      sprintf( indents, token, "" );
   }

   while( strlen( src ) ) {
      while( marker < length ) {
         if( src[marker] == '\n' )
            break;
         src = one_argument( src, word );
         wrdlen = strlen_color( word );
         // If it won't fit on the line, put it back and wrap.
         if( marker + wrdlen == length ) {
            sprintf( src, "%s %s", src, word );
            break;
         }
         sprintf( newstr, "%s %s", newstr, word );
         marker += wrdlen;
      }
      if( indent )
         sprintf( newstr, "%s%s", indents, newstr);
      sprintf( newstr, "%s\n", newstr );
      marker = indent;
   }
   // Append color reset.
   sprintf( newstr, "%s&w", newstr );
   return STRALLOC( newstr );
}
// void edit_buffer( CHAR_DATA * ch, char *argument );  [it's in editor.c] 
   if( argument[0] == '/' || argument[0] == '\\' )
   {
      argument = one_argument( argument, cmd );

      if( !str_cmp( cmd + 1, "?" ) )
         editor_help( ch, edd, argument );
      else if( !str_cmp( cmd + 1, "c" ) )
         editor_clear_buf( ch, edd, argument );
      else if( !str_cmp( cmd + 1, "r" ) )
         editor_search_and_replace( ch, edd, argument );
      else if( !str_cmp( cmd + 1, "i" ) )
         editor_insert_line( ch, edd, argument );
      else if( !str_cmp( cmd + 1, "d" ) )
         editor_delete_line( ch, edd, argument );
      else if( !str_cmp( cmd + 1, "g" ) )
         editor_goto_line( ch, edd, argument );
      else if( !str_cmp( cmd + 1, "l" ) )
         editor_list( ch, edd, argument );
      else if( !str_cmp( cmd + 1, "a" ) )
         editor_abort( ch, edd, argument );
      else if( !str_cmp( cmd + 1, "s" ) )
         editor_save( ch, edd, argument );
      else if( !str_cmp( cmd + 1, "!" ) )
         editor_escaped_cmd( ch, edd, argument );
      else if( !str_cmp( cmd + 1, "p" ) )
         editor_print_info( ch, edd, argument );
      else if( !str_cmp( cmd + 1, "f" ) )
      {
	 int indent;
	 if( !str_cmp( argument, "" ) )
	    indent = 0;
	 else
	    indent = atoi( argument );
         editor_format_lines( ch, edd, indent );
      } /* There's a lot in here that I haven't put in, and I bolded what I added */
// void editor_format_lines( CHAR_DATA * ch, EDITOR_DATA * edd, int indent ); [It's in editor.c also]
void editor_format_lines( CHAR_DATA * ch, EDITOR_DATA * edd, int indent )
{
   EDITOR_LINE *eline;
   short from, to;
   int srclen, x, inp;
   char src[MAX_STRING_LENGTH];
   char newsrc[MAX_STRING_LENGTH];
   char newsrc2[MAX_STRING_LENGTH];
   from = 1;
   to = edd->line_count;
   eline = edd->first_line;
   inp = 0;
   while( eline )
   {
      srclen = strlen( eline->line );
      for( x = 0; x < srclen; x++ )
         src[inp++] = eline->line[x];
	if(src[inp-1] != ' ')	
	    src[inp++] = ' ';
      eline = eline->next;
   }
   src[inp] = '\0';
   strcpy( newsrc, strrep( src, "(NL)", "\r\n" ) );
   strcpy( newsrc, strlinwrp( newsrc, 75, indent ) );
   edit_buffer( ch, "/c" );
   inp = 0;
   srclen = strlen( newsrc );
   for( x = 0; x < srclen; x++ )
   {
      if( newsrc[x] == '\r' || newsrc[x] == '\n' )
      {
         x++;
         newsrc2[inp] = '\0';
         inp = 0;
         edit_buffer( ch, newsrc2 );
         continue;
      }
      newsrc2[inp++] = newsrc[x];
   }
   send_to_char( "\r\nOk - Reformatted.\r\n", ch );
}

Anyway, it keeps crashing, and gdb doesn't seem to be able to catch the cause. Would anyone be able to help me?
Top

Posted by Zeno   USA  (2,871 posts)  Bio
Date Reply #1 on Sat 03 Jan 2009 07:42 PM (UTC)
Message
Can you show us what you tried with gdb?

Zeno McDohl,
Owner of Bleached InuYasha Galaxy
http://www.biyg.org
Top

Posted by Terry   USA  (87 posts)  Bio
Date Reply #2 on Sat 03 Jan 2009 07:50 PM (UTC)

Amended on Sat 03 Jan 2009 07:51 PM (UTC) by Terry

Message
Sure. I tried to do 'gdb ./startup', but that didn't work, so I just crashed it and got the core. Here's what it gave:
darkness@linux:~/swgc_code/area$ gdb ../src/swreality -c core
GNU gdb 6.8-debian
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "i486-linux-gnu"...

warning: Can't read pathname for load map: Input/output error.
Reading symbols from /lib/tls/i686/cmov/libm.so.6...done.
Loaded symbols for /lib/tls/i686/cmov/libm.so.6
Reading symbols from /usr/lib/libz.so.1...done.
Loaded symbols for /usr/lib/libz.so.1
Reading symbols from /lib/tls/i686/cmov/libdl.so.2...done.
Loaded symbols for /lib/tls/i686/cmov/libdl.so.2
Reading symbols from /usr/lib/libsqlite3.so.0...done.
Loaded symbols for /usr/lib/libsqlite3.so.0
Reading symbols from /lib/tls/i686/cmov/libc.so.6...done.
Loaded symbols for /lib/tls/i686/cmov/libc.so.6
Reading symbols from /lib/ld-linux.so.2...done.
Loaded symbols for /lib/ld-linux.so.2
Reading symbols from /lib/tls/i686/cmov/libpthread.so.0...done.
Loaded symbols for /lib/tls/i686/cmov/libpthread.so.0
Reading symbols from /lib/tls/i686/cmov/libnss_files.so.2...done.
Loaded symbols for /lib/tls/i686/cmov/libnss_files.so.2
Reading symbols from /lib/tls/i686/cmov/libnss_dns.so.2...done.
Loaded symbols for /lib/tls/i686/cmov/libnss_dns.so.2
Reading symbols from /lib/tls/i686/cmov/libresolv.so.2...done.
Loaded symbols for /lib/tls/i686/cmov/libresolv.so.2
Reading symbols from /lib/libgcc_s.so.1...done.
Loaded symbols for /lib/libgcc_s.so.1
Core was generated by `../src/swreality 6050'.
Program terminated with signal 6, Aborted.
[New process 21314]
#0 0x4001c410 in __kernel_vsyscall ()
(gdb) bt
#0 0x4001c410 in __kernel_vsyscall ()
#1 0x400f3085 in raise () from /lib/tls/i686/cmov/libc.so.6
#2 0x400f4a01 in abort () from /lib/tls/i686/cmov/libc.so.6
#3 0x4012bb7c in ?? () from /lib/tls/i686/cmov/libc.so.6
#4 0x401b5138 in __fortify_fail () from /lib/tls/i686/cmov/libc.so.6
#5 0x401b50f0 in __stack_chk_fail () from /lib/tls/i686/cmov/libc.so.6
#6 0x08138210 in strlinwrp (src=0xbf990b9a "", length=7808522, indent=0)
at handler.c:4614
#7 0x20202020 in ?? ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) frame 0
#0 0x4001c410 in __kernel_vsyscall ()
(gdb) up
#1 0x400f3085 in raise ()
(gdb) up
#2 0x400f4a01 in abort ()
(gdb) up
#3 0x4012bb7c in ?? ()
(gdb) up
#4 0x401b5138 in __fortify_fail ()
(gdb) up
#5 0x401b50f0 in __stack_chk_fail ()
(gdb) up
#6 0x08138210 in strlinwrp (src=0xbf990b9a "", length=7808522, indent=0)
at handler.c:4614
4614 }
(gdb) up
#7 0x20202020 in ?? ()
(gdb) q
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #3 on Sat 03 Jan 2009 08:30 PM (UTC)
Message
Quote:

I tried to do 'gdb ./startup', but that didn't work ...


The file startup is a shell script, so you wouldn't gdb that.

I would do something like:


cd ../area
gdb ../src/smaug

(and then in gdb, set breakpoints, and ... )

run 4000     (or whatever port you use)




- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Terry   USA  (87 posts)  Bio
Date Reply #4 on Sat 03 Jan 2009 09:10 PM (UTC)

Amended on Mon 05 Jan 2009 03:43 PM (UTC) by Terry

Message
Here's what I got:
(gdb) info break
Num Type Disp Enb Address What
1 breakpoint keep y 0x081089bb in edit_buffer at editor.c:416
2 breakpoint keep y 0x08108e18 in edit_buffer at editor.c:483
3 breakpoint keep y 0x08108e6f in edit_buffer at editor.c:490
4 breakpoint keep y 0x0813801a in strlinwrp at handler.c:4581
5 breakpoint keep y 0x08138076 in strlinwrp at handler.c:4590
6 breakpoint keep y 0x081381f1 in strlinwrp at handler.c:4613
(gdb) run

A lot of stuff came up with the boot log, but it ended here:
Sat Jan 3 16:50:03 2009 :: Initializing socket
[New Thread 0xb7ce3a30 (LWP 23788)]
Sat Jan 3 16:50:53 2009 :: Star Wars Galactic Conquest ready on port 6050.

I log in and goto a room to format:
Can't open database: unable to open database file
Sat Jan 3 16:62:24 2009 :: Log Crunch: red desc

I type //f to run the format thing
[Switching to Thread 0xb7d7ea30 (LWP 23788)]

Breakpoint 1, edit_buffer (ch=0x852c318, argument=0xbf9154e0 "/f")
at editor.c:416
416 {
(gdb) next
425 d = ch->desc;
(gdb) continue
Continuing.

Breakpoint 2, edit_buffer (ch=0x852c318, argument=0xbf9154e2 "")
at editor.c:483
483 else if( !str_cmp( cmd + 1, "f" ) )
(gdb) next
486 if( !str_cmp( argument, "" ) )
(gdb) next
487 indent = 0;
(gdb) next

Breakpoint 3, edit_buffer (ch=0x852c318, argument=0xbf954e2 "")
at editor.c:490
490 editor_format_lines( ch, edd, indent );
(gdb) next

Breakpoint 4, strlinwrp (
src=0xbf913034 "&WFrom the short hallway to the south, the massive Spaceport
Dome stretches up hundreds of feet, sloping until it reaches a magnificent peak
, a giant &wcommunications antennae&W stretching hundreds mo"..., length=75,
indent=0) at handler.c:4581
4581 {
(gdb) next
4582 int wrdlen, marker = 0;
(gdb) next
4587 if( indent ) {
(gdb) next
4592 while( strlen( src ) ) {
(gdb) next
4593 while( marker < length ) {
(gdb) next
4594 if( src[marker] == '\n' )
(gdb) next
4596 src = one_argument( src, word );
(gdb) next
4597 wrdlen = strlen_color( word );
(gdb) next
4599 if( (marker + wrdlen) == length ) {
(gdb) next
4603 sprintf( newstr, "%s %s", newstr, word );
(gdb) next
4604 marker += wrdlen;
(gdb) next
4593 while( marker < length ) {
(gdb) next
I figured nothing was going wrong here.
(gdb) continue
Continuing.

Breakpoint 6, strlinwrp (src=0xbf9132ea "", length=7808522, indent=0)
at handler.c:4613
Why's the length so insanely high...?
4613 return STRALLOC( newstr );
(gdb) next
4614 }
(gdb) next
*** stack smashing detected ***: /home/darkness/swgc_code/src/swreality terminated
======= Backtrace: =========
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x48)[0xb7e84138]
/lib/tls/i686/cmov/libc.so.6(__fortify_fail+0x0)[0xb7e840f0]
/home/darkness/swgc_code/src/swreality(strlinwrp+0x208)[0x8138210]
[0x20202020]
======= Memory map: ========
08048000-0828b000 r-xp 00000000 09:00 25150421 /home/darkness/swgc_code/src/swreality
0828b000-0828d000 rw-p 00242000 09:00 25150421 /home/darkness/swgc_code/src/swreality
0828d000-08591000 rw-p 0828d000 00:00 0 [heap]
b7d4a000-b7d54000 r-xp 00000000 08:23 450683 /lib/libgcc_s.so.1
b7d54000-b7d55000 rw-p 0000a000 08:23 450683 /lib/libgcc_s.so.1
b7d55000-b7d64000 r-xp 00000000 08:23 450599 /lib/tls/i686/cmov/libresolv-2.7.so
b7d64000-b7d66000 rw-p 0000f000 08:23 450599 /lib/tls/i686/cmov/libresolv-2.7.so
b7d66000-b7d68000 rw-p b7d66000 00:00 0
b7d68000-b7d6c000 r-xp 00000000 08:23 450592 /lib/tls/i686/cmov/libnss_dns-2.7.so
b7d6c000-b7d6e000 rw-p 00003000 08:23 450592 /lib/tls/i686/cmov/libnss_dns-2.7.so
b7d6e000-b7d77000 r-xp 00000000 08:23 450593 /lib/tls/i686/cmov/libnss_files-2.7.so
b7d77000-b7d79000 rw-p 00008000 08:23 450593 /lib/tls/i686/cmov/libnss_files-2.7.so
b7d7e000-b7d7f000 rw-p b7d7e000 00:00 0
b7d7f000-b7d93000 r-xp 00000000 08:23 450598 /lib/tls/i686/cmov/libpthread-2.7.so
b7d93000-b7d95000 rw-p 00013000 08:23 450598 /lib/tls/i686/cmov/libpthread-2.7.so
b7d95000-b7d97000 rw-p b7d95000 00:00 0
b7d97000-b7ee0000 r-xp 00000000 08:23 450584 /lib/tls/i686/cmov/libc-2.7.so
b7ee0000-b7ee1000 r--p 00149000 08:23 450584 /lib/tls/i686/cmov/libc-2.7.so
b7ee1000-b7ee3000 rw-p 0014a000 08:23 450584 /lib/tls/i686/cmov/libc-2.7.so
b7ee3000-b7ee6000 rw-p b7ee3000 00:00 0
b7ee6000-b7f49000 r-xp 00000000 08:23 1829881 /usr/lib/libsqlite3.so.0.8.6
b7f49000-b7f4b000 rw-p 00062000 08:23 1829881 /usr/lib/libsqlite3.so.0.8.6
b7f4b000-b7f4d000 r-xp 00000000 08:23 450587 /lib/tls/i686/cmov/libdl-2.7.so
b7f4d000-b7f4f000 rw-p 00001000 08:23 450587 /lib/tls/i686/cmov/libdl-2.7.so
b7f4f000-b7f50000 rw-p b7f4f000 00:00 0
b7f50000-b7f64000 r-xp 00000000 08:23 1828825 /usr/lib/libz.so.1.2.3.3
b7f64000-b7f65000 rw-p 00013000 08:23 1828825 /usr/lib/libz.so.1.2.3.3
b7f65000-b7f88000 r-xp 00000000 08:23 450588 /lib/tls/i686/cmov/libm-2.7.so
b7f88000-b7f8a000 rw-p 00023000 08:23 450588 /lib/tls/i686/cmov/libm-2.7.so
b7f8d000-b7f91000 rw-p b7f8d000 00:00 0
b7f91000-b7f92000 r-xp b7f91000 00:00 0 [vdso]
b7f92000-b7fac000 r-xp 00000000 08:23 450773 /lib/ld-2.7.so
b7fac000-b7fae000 rw-p 00019000 08:23 450773 /lib/ld-2.7.so
bf902000-bf917000 rw-p bffeb000 00:00 0 [stack]

Program received signal SIGABRT, Aborted.
0xb7f91410 in __kernel_vsyscall ()

And there she blows (up).
Top

Posted by Terry   USA  (87 posts)  Bio
Date Reply #5 on Sat 03 Jan 2009 09:32 PM (UTC)

Amended on Sat 03 Jan 2009 09:50 PM (UTC) by Terry

Message
I just did some further gdb'ing and found out that word wasn't a string... And when I did 'print word' a few times, it kept giving some random garbage... Is that common with sprintf? I tired using STRALLOC(), but it didn't ever seem to work, so I decided to use sprintf instead.

... It just came to me. WARNING! The following error will make you want to shoot me! =P It's definitely a result of coding when intoxicated by lack of sleep. ;P I did
if( (marker + wrdlen) == length ) {
on line 4599... It should've been ">=". Unfortunately, even though I changed it, it still crashes, so I guess that's not the problem...
Top

Posted by Nick Gammon   Australia  (23,070 posts)  Bio   Forum Administrator
Date Reply #6 on Sun 04 Jan 2009 08:58 AM (UTC)
Message
I'm not sure I would do this:


sprintf( newstr, "%s %s", newstr, word );


You are printing into a buffer, the word itself (newstr). I suppose it depends how much memory is allocated to newstr, but it looks strange, and conceivably sprintf would loop as the word it is copying in gets longer as it is modifying itself.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Terry   USA  (87 posts)  Bio
Date Reply #7 on Mon 05 Jan 2009 03:22 PM (UTC)

Amended on Mon 05 Jan 2009 03:28 PM (UTC) by Terry

Message
Would it be better to just do this?
newstr = sprintf( "%s %s", newstr, word );



Hmm, I tried this, and it wouldn't compile, saying that sprintf was returning an integer. I'm guessing it's returning 2 instead of the string? If so, what would you suggest I do? I'm sorry to be asking you to write code for me. =\
Top

Posted by Nick Cash   USA  (626 posts)  Bio
Date Reply #8 on Mon 05 Jan 2009 10:36 PM (UTC)

Amended on Tue 06 Jan 2009 03:10 AM (UTC) by Nick Cash

Message
sprintf returns the number of characters written, so assignments like that won't work.

The crashing is likely connected to this line:

 return STRALLOC( newstr )


The formatting code should not use STRALLOC. It is likely that the final buffer is allocated for you, and your STRALLOC here is probably wasting space in the hash table and causing a memory leak. Due to the number of times you call the function and the size of strings involved it would be easy to overwhelm the hash table or memory being used for the game itself.

What you want to do is change the function to use a static character array (you can find many in SWR to use as a prototype, such as affect_bit_type in handler.c). This avoids the allocation issues and allows you to use your function more like you intended from the looks of the code.

~Nick Cash
http://www.nick-cash.com
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


24,697 views.

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.