Thread: SIGTRAP troubleshooting

  1. #1
    Registered User ~Kyo~'s Avatar
    Join Date
    Jun 2004
    Posts
    320

    SIGTRAP troubleshooting

    Not sure how it is getting thrown.

    I know the code causing it is this
    Code:
    char* mysocket::Recv()      //Recvs a char string.
    {
        int error;
        char *buffer;
        buffer = new char[1024];
        memset(buffer, 0, strlen(buffer)); //Clear the buffer
        //Put the incoming text into our buffer
        error = recv(s, buffer, 1023, 0);
        if(error < 0 || strlen(buffer) == 0){delete buffer;return NULL;}   //recv returns -1 for a fail
        else {buffer[error] = '\0';return buffer;}
    }
    Code:
    #0 0x77b60845	ntdll!TpWaitForAlpcCompletion (??:??)
    #1 0x00f1fd10	?? (??:??)
    #2 0x77b456a2	ntdll!RtlFillMemoryUlong (??:??)
    #3 0x00694808	?? (??:??)
    #4 0x00690000	?? (??:??)
    #5 0x00694808	?? (??:??)
    #6 0x00690000	?? (??:??)
    #7 0x00f1fd30	?? (??:??)
    #8 0x77b22a44	ntdll!RtlpConvertCultureNamesToLCIDs (??:??)
    #9 0x00000000	?? (??:??)
    #10 0x00694808	?? (??:??)
    #11 0x00694808	?? (??:??)
    #12 0x77abb8e6	ntdll!RtlDowncaseUnicodeChar (??:??)
    #13 0x84070083	?? (??:??)
    #14 0x00000ee4	?? (??:??)
    #15 0x00f1fd78	?? (??:??)
    #16 0x77b6189f	ntdll!TpQueryPoolStackInformation (??:??)
    #17 0x00690000	?? (??:??)
    #18 0x00694808	?? (??:??)
    #19 0x77abb8e6	ntdll!RtlDowncaseUnicodeChar (??:??)
    #20 0x72d4d36d	?? (??:??)
    #21 0x00690000	?? (??:??)
    #22 0x00690000	?? (??:??)
    #23 0x00000000	?? (??:??)
    #24 0x00690000	?? (??:??)
    #25 0x00f1fe08	?? (??:??)
    #26 0x00010000	?? (??:??)
    #27 0x00f1fd44	?? (??:??)
    #28 0x00690000	?? (??:??)
    #29 0x00f1fe5c	?? (??:??)
    #30 0x77b00ae5	ntdll!AlpcMaxAllowedMessageLength (??:??)
    #31 0x058efea5	?? (??:??)
    #32 0x00000001	?? (??:??)
    #33 0x00f1fe6c	?? (??:??)
    #34 0x77b1a9af	ntdll!AlpcMaxAllowedMessageLength (??:??)
    #35 0x00690000	?? (??:??)
    #36 0x50000063	?? (??:??)
    #37 0x00694810	?? (??:??)
    #38 0x72d4d079	?? (??:??)
    #39 0x00000000	?? (??:??)
    #40 0x00690000	?? (??:??)
    #41 0x00694810	?? (??:??)
    #42 0x00000000	?? (??:??)
    #43 0x00000400	?? (??:??)
    #44 0x77abe046	ntdll!LdrWx86FormatVirtualImage (??:??)
    #45 0x0000001c	?? (??:??)
    #46 0x00690138	?? (??:??)
    #47 0x00000000	?? (??:??)
    #48 0x72d4d3fd	?? (??:??)
    #49 0x40000062	?? (??:??)
    #50 0x00000000	?? (??:??)
    #51 0x00690000	?? (??:??)
    #52 0x00000000	?? (??:??)
    #53 0x004ec3d8	?? (??:??)
    #54 0x00000000	?? (??:??)
    #55 0x00000000	?? (??:??)
    #56 0x00810000	?? (??:??)
    #57 0x40000062	?? (??:??)
    #58 0x00f1fd24	?? (??:??)
    #59 0x00000103	?? (??:??)
    #60 0xc000020d	?? (??:??)
    #61 0x000000a4	?? (??:??)
    #62 0x00000004	?? (??:??)
    #63 0x77ac622f	ntdll!TpCaptureCaller (??:??)
    #64 0x77ac6234	ntdll!TpCaptureCaller (??:??)
    #65 0x72d4d035	?? (??:??)
    #66 0x000000a4	?? (??:??)
    #67 0xc000020d	?? (??:??)
    #68 0x00000103	?? (??:??)
    #69 0x00f1fdf8	?? (??:??)
    #70 0x77aaf8b1	ntdll!RtlUpdateClonedSRWLock (??:??)
    #71 0x00f1fe90	?? (??:??)
    #72 0x77b00ae5	ntdll!AlpcMaxAllowedMessageLength (??:??)
    #73 0x058ee0cd	?? (??:??)
    #74 0xfffffffe	?? (??:??)
    #75 0x00000000	?? (??:??)
    #76 0x736167e4	WSHTCPIP!WSHOpenSocket2 (??:??)
    #77 0xc000020d	?? (??:??)
    #78 0xc000020d	?? (??:??)
    #79 0x00f1fea0	?? (??:??)
    #80 0x73617411	WSHTCPIP!WSHOpenSocket2 (??:??)
    #81 0x7361461c	WSHTCPIP!WSHOpenSocket2 (??:??)
    #82 0x6c0ec350	?? (??:??)
    #83 0x00000000	?? (??:??)
    #84 0x01005360	?? (??:??)
    #85 0x00000000	?? (??:??)
    #86 0x00f1fed8	?? (??:??)
    #87 0x00000001	?? (??:??)
    #88 0x00f1fd8c	?? (??:??)
    #89 0x00000020	?? (??:??)
    #90 0x00f1fec8	?? (??:??)
    #91 0x77b00ae5	ntdll!AlpcMaxAllowedMessageLength (??:??)
    #92 0x058ee665	?? (??:??)
    #93 0xfffffffe	?? (??:??)
    #94 0x00f1fe8c	?? (??:??)
    #95 0x77ac2bf2	ntdll!RtlEncodePointer (??:??)
    #96 0x00694808	?? (??:??)
    #97 0x00694810	?? (??:??)
    #98 0x00694810	?? (??:??)
    #99 0x00000000	?? (??:??)
    #100 0x00000745	?? (??:??)
    #101 0x00694808	?? (??:??)
    #102 0x00f1fed8	?? (??:??)
    #103 0x758798cd	msvcrt!free (??:??)
    #104 0x00690000	?? (??:??)
    #105 0x00000000	?? (??:??)
    #106 0x00694810	?? (??:??)
    #107 0x6c0010bb	?? (??:??)
    #108 0x00000000	?? (??:??)
    #109 0x00000000	?? (??:??)
    #110 0x00000745	?? (??:??)
    #111 0x00000001	?? (??:??)
    #112 0x00f1fef0	?? (??:??)
    #113 0x00f1fefc	?? (??:??)
    #114 0x7765305c	ntohl (??:??)
    #115 0x00f1fea0	?? (??:??)
    #116 0x00f1fee8	?? (??:??)
    #117 0x00f1ff70	?? (??:??)
    #118 0x75898cd5	msvcrt!atan2 (??:??)
    #119 0x19767683	?? (??:??)
    #120 0xfffffffe	?? (??:??)
    #121 0x00f1fee8	?? (??:??)
    #122 0x00403975	operator delete (??:??)
    Code:
    Selecting target: default
    Compiling: done
    Starting debugger: done
    Adding source dir: \Desktop\Test Server\
    Adding file: \Desktop\Test Server\console.exe
    Error: dll starting at 0x77791000 not found.
    error
    error
    error
    error
    Program received signal (SIGTRAP)
    Trace/breakpoint trap
    Previous frame inner to this frame (corrupt stack?)
    error
    Debugger finished with status 0
    Last edited by ~Kyo~; 05-23-2011 at 11:19 PM.

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > memset(buffer, 0, strlen(buffer)); //Clear the buffer
    strlen() works by looking for a \0 to begin with.
    If there is no \0 in the valid memory, then you end up clearing who knows how much of someone else's memory.

    Likewise, your next attempt at using strlen is equally flawed.

    Plus, it's completely unnecessary if you use the recv function properly.

    Here,
    Code:
    char* mysocket::Recv()      //Recvs a char string.
    {
        int error;
        char *buffer;
        buffer = new char[1024];
        //Put the incoming text into our buffer
        error = recv(s, buffer, 1023, 0);
        if(error < 0){delete buffer;return NULL;}   //recv returns -1 for a fail
        else {buffer[error] = '\0';return buffer;}
    }
    Since you're using C++, perhaps you should return a std::string version of your buffer instead.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    And you can use std::vector, too:
    Code:
    std::vector buffer(1024);
    int error = recv(s, &buffer[0], buffer.size() - 1, 0);
    if (error < 0) throw std::exception("Recieve failed");
    return buffer;
    But I am unsure of what you are recieving, so making a string out of it might not be such a good idea.
    Furthermore, you can take the vector by reference if you are worried about unnecessary copies.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  4. #4
    Registered User ~Kyo~'s Avatar
    Join Date
    Jun 2004
    Posts
    320
    Generally it could be done as a string and I probably should. I am curious why that code worked fine for the longest time and all of a sudden gave me issues. It had been performing as expected untill one compile and it went to hell. Was the error information from sigtrap helpful at all? I mean stack overflow should have pointed me to overrunning my stack of course and the only stack to overflow is the one in my recv function. I am unsure why that dll is saying error error error error now as well that was not there before.

    This is how Recv() is used currently:

    Code:
    void Server::Check_Connections(void *ptr)                                       //Checks connections for data pushes commands onto the stack to be executed later.
    {
        Server *this_class = (Server*)ptr;
        this_class->TimeToDie = false;
        this_class->oktodie[1] = false;
        while(!this_class->TimeToDie)
        {
            for(int z = 0;z < this_class->MAX_CONNECTIONS;z++)
            {
                if(this_class->Connections[z] && clock() - this_class->CONNECT_TIMES[z] >= 600000)
                {
                    delete this_class->Connections[z];
                    this_class->Connections[z] = 0;
                    cout<<"Dropping connection on socket "<<z<<" due to inactivity."<<endl;
                }
                if(this_class->Connections[z] && this_class->Connections[z]->HasData())
                {
                    My_Command *Pushable_Command;
                    Pushable_Command = new My_Command;
                    Pushable_Command->identifier = z;
                    char *data = this_class->Connections[z]->Recv();
                    Pushable_Command->Command = data;
                    if(data != NULL && (strcmp(data,"DISCONNECT") != 0))
                    {
                        do{}
                        while(!this_class->Push_Command(Pushable_Command));
                    }
                    else
                    {
                        if(data)delete data;
                        delete Pushable_Command;
                        delete this_class->Connections[z];
                        this_class->Connections[z] = 0;
                    }             //If we get nothing back from a read something is probably wrong cull that connection.
                }
            }
        }
        this_class->oktodie[1] = true;
        _endthread();
    }

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    > I am curious why that code worked fine for the longest time and all of a sudden gave me issues.
    That's what undefined behaviour is all about. Things can seem to 'work' for months or even years, then all of a sudden - not work.

    > Was the error information from sigtrap helpful at all?
    I knew what was wrong as soon as I saw strlen being used where it shouldn't.
    Stack traces filled with ?? references generally mean something really bad happened, and should not be relied on to give you too much useful information.

    It is weird why it was trashed though, since the memory being over-cleared is heap memory.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User ~Kyo~'s Avatar
    Join Date
    Jun 2004
    Posts
    320
    One more question as I am off to work lol... What would cause a program to have normal expected operation when run through a debugger, but if you use the .exe it crashes horribly in unpredictable places. For example it will run through one command then crash or it might not run through one command or it may run a couple commands. When run in debug mode I can send command after command and not get it to crash and recreate the issue so I can backtrack. Not sure how to troubleshoot this or even which thread is crashing out.

  7. #7
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Most likely race conditions, then. They are a pain.
    Some tips:
    - Make SURE you have proper synching primitives. Always lock before a critical region, and always unlock when exiting. No exceptions.
    - Add asserts in your code to test the state of your program.
    - Use a JIT debugger (for example, Visual Studio).
    - Use smart pointers, or avoid raw pointers and new altogether.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Features of debug builds include
    - variables (and allocated memory) might be initialised to a constant 'junk' value, rather than being truly random, to help detect "use before initialisation"
    - variables on the stack may be surrounded by dead zones, to detect buffer overruns. malloc'ed memory may have similar DMZ's at the ends as well.
    - memory might not be truly freed when you call free, to detect any "use after free" bugs.

    > Not sure how to troubleshoot this or even which thread is crashing out.
    Add to that, since a debug thread does a different amount of work, subtle timing errors may (or not) affect the outcome.

    Some bugs you just have to comb the code for, and you have to think your way out of the problem.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  9. #9
    Registered User ~Kyo~'s Avatar
    Join Date
    Jun 2004
    Posts
    320
    It alsmost doesn't seem like a threading issue since if I telnet to the server and send single characters it works fine must be inside the function I am calling... I belive I am using function pointers correctly at least in this case. My implementation follows

    Code:
    void build_command_map()
    {
        Functions[0] = new CommandToFunct;
        Functions[0]->Command = new char[strlen("LOGIN")];
        strcpy(Functions[0]->Command,"LOGIN");
        Functions[0]->Funct = &Login;
    
    
    }
    void HandleCommand(My_Command* cmd)         //LOGIN_NAME_PASSWORD
    {
        char *str = new char[strlen(cmd->Command)];
        strcpy(str,cmd->Command);
        char * pch;
        pch = strtok (str,"_");
        if(pch && strcmp(pch,"LOGIN")==0)
        {
            (*Functions[0]->Funct)(cmd);
        }
        delete cmd;
    
    }
    
    void Login(My_Command* cmd)
    {
        char *str = new char[strlen(cmd->Command)];
        strcpy(str,cmd->Command);
        char * pch;
        pch = strtok (str,"_");
        if(strcmp(pch,"LOGIN") == 0)
        {
            char *n = strtok (NULL,"_");
            char *p = strtok (NULL,"_");
            cout<<"Login: "<<n<<"  Password: "<<p<<endl;
            for(int i=0;i<MAX_CONNECTIONS_TO_SERVER;i++)
            {
                if(characters[i] == NULL)
                {
                    characters[i] = new Character;
                    if(characters[i]->Login(n,p))
                    {
                        Test_Server->SendToPlayer(cmd->identifier,"LOGIN_OK");
                    }else
                    {
                        Test_Server->SendToPlayer(cmd->identifier,"LOGIN_FAIL");
                        delete characters[i];
                    }
                    break;
                }
            }
        }
        delete str;
    }
    Last edited by ~Kyo~; 05-25-2011 at 03:01 PM.

  10. #10
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    You have buffer overruns in every strcpy statement.
    Why do you use C-style strings instead of C++ ones? That would make the string handling much easier and safer.

    new[] and delete don't match. Use corresponding delete [] for new [], or just use std::string.

    Do you need that many pointers? For example, Functions[0]. Can you not just fill in that struct/class instead of having create a new one using new and then initialize it?
    Last edited by Elysia; 05-25-2011 at 03:03 PM.
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

  11. #11
    Registered User ~Kyo~'s Avatar
    Join Date
    Jun 2004
    Posts
    320
    Actually I did start to go back last night and change from char* to string. Catch is in some places it was going to have me cast string to char*. Yes there is a command for it in string not that I remember what it is off the top of my head, but I know it is there. You are right though should have been delete[]ing and doing strlen +1.

  12. #12
    Registered User
    Join Date
    Aug 2003
    Posts
    1,218
    const char* string::c_str() const
    is the function to get the c-style string. Note all the consts.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Troubleshooting Please
    By jsking09 in forum C Programming
    Replies: 3
    Last Post: 03-03-2010, 02:37 AM
  2. My program needs troubleshooting...
    By Rockiroad278 in forum C Programming
    Replies: 7
    Last Post: 12-16-2007, 08:34 PM
  3. Troubleshooting code
    By bcianfrocca in forum C++ Programming
    Replies: 11
    Last Post: 11-17-2005, 05:46 PM
  4. Troubleshooting
    By hockeydrummer88 in forum C++ Programming
    Replies: 1
    Last Post: 03-08-2005, 02:17 PM
  5. Troubleshooting DDE
    By musicafterhours in forum Windows Programming
    Replies: 3
    Last Post: 11-18-2001, 08:26 AM