CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8

Threaded View

  1. #1
    Join Date
    Jan 2012
    Posts
    2

    Memory corruption with std::map and malloc

    I'm having a problem with corrupted memory. The memory has previously been allocated by malloc() in order to hold an array of struct pollfds. A pointer to this array is stored in a member called 'poll_fds'. There is another member called 'buffers', which is an STL map container. This member is intended to store a number of strings, which are used as buffers, and is keyed on an int, which is the file descriptor from which input is being read. When I attempt to insert a new element into the map, it appears that the memory allocated by malloc() and used to store the struct pollfds is overwritten by at least some of the data (the key) that is inserted into the map.

    I'll give some quick background to this before providing a code snippet and output which demonstrates my problem. This module is part of a piece of software which listens on a network port for an incoming connection (usually only one at a time, but potentially more), accepts the connection and then reads lines of data (call logging records from a telephone system). This data is passed back from the IO_Net module into main(), and then another module (IO_DBase) is used to store this data in a database. In the course of debugging this issue I have cut out the majority of the code, leaving me with only the essential pieces that I need to isolate/demonstrate the issue (what I'm trying to say is that the complete code does properly handle reading data, closing connections, etc., but this has been cut as it is not required to demonstrate the problem...).

    Here's a snippet of code from the accept_conn() method, which accepts the incoming connection, adds a buffer for the new connection, and adds the fd to the array of fds being polled. This particular snippet just highlights the line where I see the corruption, with the surrounding debugging output code:
    Code:
        std::cerr << "pollfds during accept1:";
        // Check that the supplied fd does not already exist in our array
        for (poll_fd = this->poll_fds;
             poll_fd < (this->poll_fds + (this->poll_nfds * sizeof(struct pollfd)));
             poll_fd += sizeof(struct pollfd)) {
                std::cerr << " " << poll_fd->fd << " (";
                fprintf(stderr, "%p", poll_fd);
                std::cerr << ")";
        }
        std::cerr << std::endl;
    
        (this->buffers).insert(std::pair<int, std::string>(new_fd, ""));
    
        std::cerr << "pollfds during accept2:";
        // Check that the supplied fd does not already exist in our array
        for (poll_fd = this->poll_fds;
             poll_fd < (this->poll_fds + (this->poll_nfds * sizeof(struct pollfd)));
             poll_fd += sizeof(struct pollfd)) {
                std::cerr << " " << poll_fd->fd << " (";
                fprintf(stderr, "%p", poll_fd);
                std::cerr << ")";
        }
        std::cerr << std::endl;
    I'll attach a tarball of the source files and Makefile that I'm using. To reproduce, run loggerd, and then start a netcat session to localhost on port 5000 ('nc localhost 5000'). While this first connection is active, run a second netcat session also to localhost on port 5000. Note that on some runs get_callrec() loops infinitely after the first connection is made, presumably because data arrives on the connection that we do not read in this cut-down version of the code. At most a couple of runs are usually required before the problem can be reproduced.

    Here's the output that I get:
    Code:
    pollfds before:
    pollfds after: 3 (0xa4b060)
    polling... polled
    pollfds during accept1: 3 (0xa4b060)
    pollfds during accept2: 3 (0xa4b060)
    pollfds before: 3 (0xa4b060)
    pollfds after: 3 (0xa4b0c0) 4 (0xa4b100)
    polling... polled
    pollfds during accept1: 3 (0xa4b0c0) 4 (0xa4b100)
    pollfds during accept2: 3 (0xa4b0c0) 5 (0xa4b100)
    pollfds before: 3 (0xa4b0c0) 5 (0xa4b100)
    terminate called after throwing an instance of 'std::ios_base::failure'
      what():  Attempt to add already existing fd (5) to the poll_fds array
    Aborted
    The first occurrence of 'pollfds before' and 'pollfds after' is the call to pollfd_add() which adds the listener, the second occurrence is when the first connection is added, and on the third call to pollfd_add() an exception is raised because the fd already exists in the poll_fds array (as a result of memory corruption). Note the change in the poll_fds array between 'pollfds during accept1' and 'pollfds during accept2', just before the second fd is added (i.e. when the second concurrent connection is made). The only line of code between these output statements is the line which inserts a new element into the buffers map.

    I'm sure this is probably just something silly that I've done, but I can't see what it is. Any help would be most appreciated.
    Attached Files Attached Files

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured