I have a dynamic library, how to know if it calls malloc during run-time?
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_nto开发者_如何学编程a(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;
}
ltrace
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.
精彩评论