Ok. Ok. Ok. Ok. .....

Posted by Nick Cash on Tue 27 Jan 2004 04:37 AM — 5 posts, 12,677 views.

USA #0
Well, I've got a problem, but for once, its not fatal. My mud, for some reason, has started saying Ok. every couple seconds. Its in dark blue, and I have no clue why. I'm sure its prolly a run away function thats repeating, but there are dozens of entries in all the .c files containing the exact prhase Ok. Are there any ways to determine which one is looping rather then go through each one?

Thanks.
Canada #1
Well, if its every few seconds, it likely in update.c, or one of the other updates. Did you perhaps put "do_save(ch, "")" in the character update? Just think back to what you've changed. You could also grep for something like "&bOk."
Australia Forum Administrator #2
This would be a great place to try out gdb. :)

I did an example which would show how this should work for you.

Start up gdb:

gdb ../src/smaug

The "Ok" ends up on the player's screen, so let's put a breakpoint in write_to_buffer ...

break write_to_buffer
Breakpoint 1 at 0x80bcb33: file comm.c, line 1610.
(gdb)


Now let's see what arguments write_to_buffer has ...

list write_to_buffer
1602
1603    /*
1604     * Append onto an output buffer.
1605     */
1606    void write_to_buffer( DESCRIPTOR_DATA *d, const char *txt, int length )
1607    {
1608    int origlength;
1609
1610        if ( !d )
1611        {
(gdb)



The thing being written is "txt", so let's see if that has "Ok" somewhere in it...

cond 1 strstr (txt, "Ok") != 0

That will make it break *only* if the thing being written contains "Ok" (which is not all that often). The exact syntax here is:

cond[ition] <breakpoint> <condition>

Since the breakpoint was breakpoint 1 (the first and only breakpoint) then I typed "cond 1" followed by the condition for the breakpoint.

Now run it:

run

It loads its areas and gets on with it. All should be fine, but if I type (say) "think Ok" into my client, the breakpoint triggers ...



Breakpoint 1, write_to_buffer(descriptor_data*, char const*, int) (
    d=0x8578908, txt=0xbfff8da0 "You think 'Ok'\n\r", length=16) at comm.c:1610
1610        if ( !d )
(gdb)


Aha! It breaks and "txt" (above) has Ok in it. Now let's find out where it came from (by typing bt) ...


(gdb) bt
#0  write_to_buffer(descriptor_data*, char const*, int) (d=0x8578908,
    txt=0xbfff8da0 "You think 'Ok'\n\r", length=16) at comm.c:1610
#1  0x080bfb2d in send_to_char(char const*, char_data*) (
    txt=0xbfff8da0 "You think 'Ok'\n\r", ch=0x857a9f0) at comm.c:2726
#2  0x080c0441 in ch_printf(char_data*, char*, ...) (ch=0x857a9f0,
    fmt=0x8191354 "You %s '%s'\n\r") at comm.c:2965
#3  0x0804aee8 in talk_channel(char_data*, char*, int, char const*) (
    ch=0x857a9f0, argument=0xbfffe726 "Ok", channel=8192,
    verb=0x819143b "think") at act_comm.c:447
#4  0x0804c40e in do_think(char_data*, char*) (ch=0x857a9f0,
    argument=0xbfffe726 "Ok") at act_comm.c:896
#5  0x08100d7f in interpret(char_data*, char*) (ch=0x857a9f0,
    argument=0xbfffe726 "Ok") at interp.c:738
#6  0x080bae81 in game_loop() () at comm.c:738
#7  0x080ba242 in main (argc=1, argv=0xbfffec24) at comm.c:322
#8  0x420156a4 in __libc_start_main () from /lib/tls/libc.so.6
(gdb)



In my example you can see (frame 4) that it came from do_think, which is what I expect, called from interpret, called from game_loop.

In your case you will find exactly the line that generates the "Ok" call. Easy.
Amended on Wed 28 Jan 2004 01:59 AM by Nick Gammon
USA #3
Amazing! Wow, thats pretty handy. It was some malicious code I wrote for an update in update.c that had to do with my ship upgrades. Thanks. My builders may now resume their work without do_save spam. :)
Australia Forum Administrator #4
An alternative way of setting up the debug session, which involves less typing and looks a bit more intuitive is to do this (3 lines of typing in total):


$ gdb ../src/smaug
(gdb) break write_to_buffer if strstr (txt, "Ok") != 0
Breakpoint 1 at 0x80a8121: file comm.c, line 1305.
(gdb) run


This assumes you know your code and know what the argument to write_to_buffer is (namely "txt") however this is a reasonable assumption.

By putting "if" on a breakpoint you are specifying a condition as you enter the breakpoint.