views:

122

answers:

2

Hi, I need to do networking in uCsimm, Motorola Dragon Ball. As I'm running uClinux with RTAI patch, and I need real-time performance, therefore all malloc and its friends are undesirable. I have the following piece of code for socket dynamic library. How to know that it calls malloc during run-time? When I compiled in cygwin on Windows, I used cygwin and found that it uses malloc, calloc, realloc & free. How to find out on Ubuntu/Linux which functions are called during run-time? Thanks in advance!

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
/* BUFFER_LEN is 4096 bytes */
#define BUFFER_LEN 4096
/* receiver port number */
#define RECEIVERPORT 2009
/* Variable and structure definitions. */
int receiver_socket_d, client_socket_d, ret_val;
unsigned int length = sizeof (unsigned int);
int totalcnt = 0, on = 1;
char temp;
char buffer[BUFFER_LEN];
struct sockaddr_in serveraddr;
struct sockaddr_in their_addr;
fd_set read_fd;
struct timeval timeout;
int receiver_setup()
{
    timeout.tv_sec = 5;
    timeout.tv_usec = 0;
    /* The socket() function returns a socket descriptor */
    /* representing an endpoint. The statement also */
    /* identifies that the INET (Internet Protocol) */
    /* address family with the TCP transport (SOCK_STREAM) */
    /* will be used for this socket. */
    /************************************************/
    /* Get a socket descriptor */
    if ((receiver_socket_d = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
        //perror("receiver-socket() error");
        /* Just exit */
        exit(-1);
    } else
        //printf("receiver-socket() is OK\n");
    /* The setsockopt() function is used to allow */
    /* the local address to be reused when the server */
    /* is restarted before the required wait time */
    /* expires. */
    /***********************************************/
    /* Allow socket descriptor to be reusable */
    if ((ret_val = setsockopt(receiver_socket_d, SOL_SOCKET, SO_REUSEADDR, (char *) & on, sizeof (on))) < 0) {
        //perror("receiver-setsockopt() error");
        close(receiver_socket_d);
        exit(-1);
    } else
        //printf("receiver-setsockopt() is OK\n");
    /* bind to an address */
    memset(&serveraddr, 0x00, sizeof (struct sockaddr_in));
    serveraddr.sin_family = AF_INET;
    serveraddr.sin_port = htons(RECEIVERPORT);
    serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
    //printf("Using %s, listening at %d\n", inet_ntoa(serveraddr.sin_addr), RECEIVERPORT);
    /* After the socket descriptor is created, a bind() */
    /* function gets a unique name for the socket. */
    /* In this example, the user sets the */
    /* s_addr to zero, which allows the system to */
    /* connect to any client that used port 3005. */
    if ((ret_val = bind(receiver_socket_d, (struct sockaddr *) & serveraddr, sizeof (serveraddr))) < 0) {
        //perror("receiver-bind() error");
        /* Close the socket descriptor */
        close(receiver_socket_d);
        /* and just exit */
        exit(-1);
    } else
        //printf("receiver-bind() is OK\n");
    /* The listen() function allows the server to accept */
    /* incoming client connections. In this example, */
    /* the backlog is set to 10. This means that the */
    /* system can queue up to 10 connection requests before */
    /* the system starts rejecting incoming requests.*/
    /*************************************************/
    /* Up to 10 clients can be queued */
    if ((ret_val = listen(receiver_socket_d, 10)) < 0) {
        //perror("receiver-listen() error");
        close(receiver_socket_d);
        exit(-1);
    } else
        //printf("receiver-Ready for client connection...\n");
    return 0;
}
int receiver_wait()
{
    /* The server will accept a connection request */
    /* with this accept() function, provided the */
    /* connection request does the following: */
    /* - Is part of the same address family */
    /* - Uses streams sockets (TCP) */
    /* - Attempts to connect to the specified port */
    /***********************************************/
    /* accept() the incoming connection request. */
    unsigned int sin_size = sizeof (struct sockaddr_in);
    if ((client_socket_d = accept(receiver_socket_d, (struct sockaddr *) & their_addr, &sin_size)) < 0) {
        //perror("receiver-accept() error");
        close(receiver_socket_d);
        exit(-1);
    } else
        //printf("receiver-accept() is OK\n");
    /*client IP*/
    //printf("receiver-new socket, client_socket_d is OK...\n");
    //printf("Got connection from client: %s\n", inet_ntoa(their_addr.sin_addr));
    /* The select() function allows the process to */
    /* wait for an event to occur and to wake up */
    /* the process when the event occurs. In this */
    /* example, the system notifies the process */
    /* only when data is available to read. */
    /***********************************************/
    /* Wait for up to 15 seconds on */
    /* select() for data to be read. */
    FD_ZERO(&read_fd);
    FD_SET(client_socket_d, &read_fd);
    ret_val = select(client_socket_d + 1, &read_fd, NULL, NULL, &timeout);
    return 0;
};
int receiver_read()
{
    buffer[0] = 0;
    buffer[1] = 0;
    totalcnt = 0;
    if ((ret_val == 1) && (FD_ISSET(client_socket_d, &read_fd))) {
        /* Read data from the client. */
        while ( (totalcnt < BUFFER_LEN) && (ret_val > 0) ) {
            /* When select() indicates that there is data */
            /* available, use the read() function to read */
            /* 4096 bytes of the string that the */
            /* client sent. */
            /***********************************************/
            /* read() from client */
            ret_val = read(client_socket_d, &buffer[totalcnt], (BUFFER_LEN - totalcnt));
            //printf("Received data from client: %s\n\n", buffer);
            if (ret_val < 0) {
                //perror("receiver-read() error");
                close(receiver_socket_d);
                close(client_socket_d);
                exit(-1);
            } else if (ret_val == 0) {
                //printf("Client program has issued a close()\n");
                //close(receiver_socket_d);
                //close(client_socket_d);
                //exit(-1);
            } else {
                totalcnt += ret_val;
                //printf("receiver-read() is OK\n");
            }
        }
    } else if (ret_val < 0) {
        //perror("receiver-select() error");
        close(receiver_socket_d);
        close(client_socket_d);
        exit(-1);
    } else {/* ret_val == 0 */
        //printf("receiver-select() timed out.\n");

        close(client_socket_d);
        receiver_wait();
        //close(receiver_socket_d);
        //exit(-1);
    }

    return 0;
}
+2  A: 

ltrace

Jonathan Feinberg
Thanks Jonathan! I'll look into this :)
Viet
Way to use your reputation privliges
Nathan
Should I know what you're talking about?
Jonathan Feinberg
+1  A: 

You can try executing your program with strace to monitor system calls.

strace [-dffhiqrtttTvVxx] [-a column] [-e expr] ... [-o file] [-p pid] ... [-s strsize] [-u username] [-E var=val] ... [command [arg ...]]

e.g.

starce ls

Also you can use valgrind to count the allocations

wild eyalm # valgrind ls
...
==15144== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 23 from 1)
==15144== malloc/free: in use at exit: 21,159 bytes in 36 blocks.
==15144== malloc/free: 124 allocs, 88 frees, 31,944 bytes allocated.
==15144== For counts of detected errors, rerun with: -v
==15144== searching for pointers to 36 not-freed blocks.
==15144== checked 105,612 bytes.
==15144==
==15144== LEAK SUMMARY:
==15144==    definitely lost: 0 bytes in 0 blocks.
==15144==      possibly lost: 0 bytes in 0 blocks.
==15144==    still reachable: 21,159 bytes in 36 blocks.
==15144==         suppressed: 0 bytes in 0 blocks.
eyalm
strace is no good as not every malloc call will result in a system call. As mentioned above, ltrace should be used instead
Demiurg
Viet