the tracee (lte-softmodem) now sends the content of T_messages.txt
as special events. If we store all received events to a file, this dump is now self-contained. Helps to analyze traces. Some functions have also been factorized in the process, too much duplication. (Also tracer/Makefile was forgotten in previous commit, included in this one...)
This commit is contained in:
@@ -24,11 +24,16 @@ $(PROG): $(OBJS)
|
||||
%.o: %.c
|
||||
$(CC) $(CFLAGS) -c -o $@ $<
|
||||
|
||||
T.o: T_messages.txt.h
|
||||
|
||||
T_messages.txt.h: T_messages.txt
|
||||
xxd -i T_messages.txt > T_messages.txt.h
|
||||
|
||||
T_IDs.h: $(GENIDS) T_messages.txt
|
||||
./$(GENIDS) T_messages.txt T_IDs.h
|
||||
|
||||
main.o: T.h T_IDs.h T_defs.h
|
||||
|
||||
clean:
|
||||
rm -f *.o $(PROG) $(GENIDS) core T_IDs.h
|
||||
rm -f *.o $(PROG) $(GENIDS) core T_IDs.h T_messages.txt.h
|
||||
cd tracer && make clean
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include "T.h"
|
||||
#include "T_messages.txt.h"
|
||||
#include <string.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <arpa/inet.h>
|
||||
@@ -125,6 +126,8 @@ void T_connect_to_tracer(char *addr, int port)
|
||||
#ifdef T_USE_SHARED_MEMORY
|
||||
int T_shm_fd;
|
||||
#endif
|
||||
unsigned char *buf;
|
||||
int len;
|
||||
|
||||
if (strcmp(addr, "127.0.0.1") != 0) {
|
||||
printf("error: local tracer must be on same host\n");
|
||||
@@ -169,4 +172,29 @@ again:
|
||||
new_thread(T_send_thread, NULL);
|
||||
#endif
|
||||
new_thread(T_receive_thread, NULL);
|
||||
|
||||
/* trace T_message.txt
|
||||
* Send several messages -1 with content followed by message -2.
|
||||
* We can't use the T macro directly, events -1 and -2 are special.
|
||||
*/
|
||||
buf = T_messages_txt;
|
||||
len = T_messages_txt_len;
|
||||
while (len) {
|
||||
int send_size = len;
|
||||
if (send_size > T_PAYLOAD_MAXSIZE - sizeof(int))
|
||||
send_size = T_PAYLOAD_MAXSIZE - sizeof(int);
|
||||
do {
|
||||
T_LOCAL_DATA
|
||||
T_HEADER(T_ID(-1));
|
||||
T_PUT_buffer(1, ((T_buffer){addr:(buf), length:(len)}));
|
||||
T_SEND();
|
||||
} while (0);
|
||||
buf += send_size;
|
||||
len -= send_size;
|
||||
}
|
||||
do {
|
||||
T_LOCAL_DATA
|
||||
T_HEADER(T_ID(-2));
|
||||
T_SEND();
|
||||
} while (0);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,13 @@
|
||||
/* size of the local cache for messages (must be pow(2,something)) */
|
||||
#define T_CACHE_SIZE (8192 * 2)
|
||||
|
||||
/* maximum number of bytes a message can contain */
|
||||
#ifdef T_SEND_TIME
|
||||
# define T_PAYLOAD_MAXSIZE (T_BUFFER_MAX-sizeof(int)-sizeof(struct timespec))
|
||||
#else
|
||||
# define T_PAYLOAD_MAXSIZE (T_BUFFER_MAX-sizeof(int))
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
volatile int busy;
|
||||
char buffer[T_BUFFER_MAX];
|
||||
|
||||
@@ -4,7 +4,7 @@ local:
|
||||
make -f Makefile.local
|
||||
|
||||
remote:
|
||||
make -f Makefile.remote tracer_remote textlog enb vcd
|
||||
make -f Makefile.remote textlog enb vcd
|
||||
|
||||
clean:
|
||||
make -f Makefile.local clean
|
||||
|
||||
@@ -5,15 +5,15 @@ CFLAGS=-Wall -g -pthread -DT_TRACER -I.
|
||||
|
||||
LIBS=-lX11 -lm -lpng -lXft
|
||||
|
||||
textlog: utils.o textlog.o database.o event.o handler.o \
|
||||
textlog: utils.o textlog.o database.o event.o handler.o config.o \
|
||||
event_selector.o view/view.a gui/gui.a logger/logger.a
|
||||
$(CC) $(CFLAGS) -o textlog $^ $(LIBS)
|
||||
|
||||
enb: utils.o enb.o database.o event.o handler.o \
|
||||
enb: utils.o enb.o database.o event.o handler.o config.o \
|
||||
event_selector.o view/view.a gui/gui.a logger/logger.a
|
||||
$(CC) $(CFLAGS) -o enb $^ $(LIBS)
|
||||
|
||||
vcd: utils.o vcd.o database.o event.o handler.o \
|
||||
vcd: utils.o vcd.o database.o event.o handler.o config.o \
|
||||
event_selector.o view/view.a gui/gui.a logger/logger.a
|
||||
$(CC) $(CFLAGS) -o vcd $^ $(LIBS)
|
||||
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static char *local;
|
||||
static int local_size;
|
||||
static char *remote;
|
||||
static int remote_size;
|
||||
|
||||
static char *PUT(char *to, int tosize, char c)
|
||||
{
|
||||
if ((tosize & 4095) == 0) {
|
||||
to = realloc(to, tosize + 4096); if (to == NULL) abort();
|
||||
}
|
||||
to[tosize] = c;
|
||||
return to;
|
||||
}
|
||||
|
||||
void append_received_config_chunk(char *buf, int length)
|
||||
{
|
||||
int buflen = *(int *)buf;
|
||||
if (buflen != length - sizeof(int)) {
|
||||
printf("ERROR: bad trace -1, should not happen...\n");
|
||||
abort();
|
||||
}
|
||||
buf += sizeof(int);
|
||||
while (buflen) {
|
||||
remote = PUT(remote, remote_size, *buf);
|
||||
remote_size++;
|
||||
buf++;
|
||||
buflen--;
|
||||
}
|
||||
}
|
||||
|
||||
void store_config_file(char *filename)
|
||||
{
|
||||
int c;
|
||||
FILE *f = fopen(filename, "r");
|
||||
if (f == NULL) { perror(filename); abort(); }
|
||||
while (1) {
|
||||
c = fgetc(f); if (c == EOF) break;
|
||||
local = PUT(local, local_size, c);
|
||||
local_size++;
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
void verify_config(void)
|
||||
{
|
||||
if (local_size != remote_size || memcmp(local, remote, local_size) != 0) {
|
||||
printf("ERROR: local and remote T_messages.txt not identical\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#ifndef _CONFIG_H_
|
||||
#define _CONFIG_H_
|
||||
|
||||
void append_received_config_chunk(char *buf, int length);
|
||||
void store_config_file(char *filename);
|
||||
void verify_config(void);
|
||||
|
||||
#endif /* _CONFIG_H_ */
|
||||
@@ -1,8 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include "database.h"
|
||||
#include "event.h"
|
||||
@@ -14,39 +12,10 @@
|
||||
#include "../T_defs.h"
|
||||
#include "event_selector.h"
|
||||
#include "openair_logo.h"
|
||||
#include "config.h"
|
||||
|
||||
#define DEFAULT_REMOTE_PORT 2021
|
||||
|
||||
int get_connection(char *addr, int port)
|
||||
{
|
||||
struct sockaddr_in a;
|
||||
socklen_t alen;
|
||||
int s, t;
|
||||
|
||||
printf("waiting for connection on %s:%d\n", addr, port);
|
||||
|
||||
s = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s == -1) { perror("socket"); exit(1); }
|
||||
t = 1;
|
||||
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int)))
|
||||
{ perror("setsockopt"); exit(1); }
|
||||
|
||||
a.sin_family = AF_INET;
|
||||
a.sin_port = htons(port);
|
||||
a.sin_addr.s_addr = inet_addr(addr);
|
||||
|
||||
if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); }
|
||||
if (listen(s, 5)) { perror("bind"); exit(1); }
|
||||
alen = sizeof(a);
|
||||
t = accept(s, (struct sockaddr *)&a, &alen);
|
||||
if (t == -1) { perror("accept"); exit(1); }
|
||||
close(s);
|
||||
|
||||
printf("connected\n");
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
printf(
|
||||
@@ -66,45 +35,6 @@ void usage(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int fullread(int fd, void *_buf, int count)
|
||||
{
|
||||
char *buf = _buf;
|
||||
int ret = 0;
|
||||
int l;
|
||||
while (count) {
|
||||
l = read(fd, buf, count);
|
||||
if (l <= 0) { printf("read socket problem\n"); abort(); }
|
||||
count -= l;
|
||||
buf += l;
|
||||
ret += l;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
event get_event(int s, char *v, void *d)
|
||||
{
|
||||
#ifdef T_SEND_TIME
|
||||
struct timespec t;
|
||||
#endif
|
||||
int type;
|
||||
int32_t length;
|
||||
|
||||
fullread(s, &length, 4);
|
||||
#ifdef T_SEND_TIME
|
||||
fullread(s, &t, sizeof(struct timespec));
|
||||
length -= sizeof(struct timespec);
|
||||
#endif
|
||||
fullread(s, &type, sizeof(int));
|
||||
length -= sizeof(int);
|
||||
fullread(s, v, length);
|
||||
|
||||
#ifdef T_SEND_TIME
|
||||
return new_event(t, type, length, v, d);
|
||||
#else
|
||||
return new_event(type, length, v, d);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void *gui_thread(void *_g)
|
||||
{
|
||||
gui *g = _g;
|
||||
@@ -228,6 +158,8 @@ int main(int n, char **v)
|
||||
|
||||
database = parse_database(database_filename);
|
||||
|
||||
store_config_file(database_filename);
|
||||
|
||||
number_of_events = number_of_ids(database);
|
||||
is_on = calloc(number_of_events, sizeof(int));
|
||||
if (is_on == NULL) abort();
|
||||
|
||||
@@ -1,9 +1,48 @@
|
||||
#include "event.h"
|
||||
#include "database.h"
|
||||
#include "utils.h"
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
event get_event(int socket, char *event_buffer, void *database)
|
||||
{
|
||||
#ifdef T_SEND_TIME
|
||||
struct timespec t;
|
||||
#endif
|
||||
int type;
|
||||
int32_t length;
|
||||
|
||||
/* Events type -1 and -2 are special: the tracee sends its version
|
||||
* of T_messages.txt using those events.
|
||||
* We have to check that the local version of T_messages.txt is identical
|
||||
* to the one the tracee uses. We don't report those events to the
|
||||
* application.
|
||||
*/
|
||||
|
||||
again:
|
||||
fullread(socket, &length, 4);
|
||||
#ifdef T_SEND_TIME
|
||||
fullread(socket, &t, sizeof(struct timespec));
|
||||
length -= sizeof(struct timespec);
|
||||
#endif
|
||||
fullread(socket, &type, sizeof(int));
|
||||
length -= sizeof(int);
|
||||
fullread(socket, event_buffer, length);
|
||||
|
||||
if (type == -1) append_received_config_chunk(event_buffer, length);
|
||||
if (type == -2) verify_config();
|
||||
|
||||
if (type == -1 || type == -2) goto again;
|
||||
|
||||
#ifdef T_SEND_TIME
|
||||
return new_event(t, type, length, event_buffer, database);
|
||||
#else
|
||||
return new_event(type, length, event_buffer, database);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef T_SEND_TIME
|
||||
event new_event(struct timespec sending_time, int type,
|
||||
int length, char *buffer, void *database)
|
||||
|
||||
@@ -37,6 +37,8 @@ typedef struct {
|
||||
int ecount;
|
||||
} event;
|
||||
|
||||
event get_event(int s, char *v, void *d);
|
||||
|
||||
#ifdef T_SEND_TIME
|
||||
event new_event(struct timespec sending_time, int type,
|
||||
int length, char *buffer, void *database);
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include "database.h"
|
||||
#include "event.h"
|
||||
@@ -13,39 +11,10 @@
|
||||
#include "utils.h"
|
||||
#include "../T_defs.h"
|
||||
#include "event_selector.h"
|
||||
#include "config.h"
|
||||
|
||||
#define DEFAULT_REMOTE_PORT 2021
|
||||
|
||||
int get_connection(char *addr, int port)
|
||||
{
|
||||
struct sockaddr_in a;
|
||||
socklen_t alen;
|
||||
int s, t;
|
||||
|
||||
printf("waiting for connection on %s:%d\n", addr, port);
|
||||
|
||||
s = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s == -1) { perror("socket"); exit(1); }
|
||||
t = 1;
|
||||
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int)))
|
||||
{ perror("setsockopt"); exit(1); }
|
||||
|
||||
a.sin_family = AF_INET;
|
||||
a.sin_port = htons(port);
|
||||
a.sin_addr.s_addr = inet_addr(addr);
|
||||
|
||||
if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); }
|
||||
if (listen(s, 5)) { perror("bind"); exit(1); }
|
||||
alen = sizeof(a);
|
||||
t = accept(s, (struct sockaddr *)&a, &alen);
|
||||
if (t == -1) { perror("accept"); exit(1); }
|
||||
close(s);
|
||||
|
||||
printf("connected\n");
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
printf(
|
||||
@@ -67,45 +36,6 @@ void usage(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int fullread(int fd, void *_buf, int count)
|
||||
{
|
||||
char *buf = _buf;
|
||||
int ret = 0;
|
||||
int l;
|
||||
while (count) {
|
||||
l = read(fd, buf, count);
|
||||
if (l <= 0) { printf("read socket problem\n"); abort(); }
|
||||
count -= l;
|
||||
buf += l;
|
||||
ret += l;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
event get_event(int s, char *v, void *d)
|
||||
{
|
||||
#ifdef T_SEND_TIME
|
||||
struct timespec t;
|
||||
#endif
|
||||
int type;
|
||||
int32_t length;
|
||||
|
||||
fullread(s, &length, 4);
|
||||
#ifdef T_SEND_TIME
|
||||
fullread(s, &t, sizeof(struct timespec));
|
||||
length -= sizeof(struct timespec);
|
||||
#endif
|
||||
fullread(s, &type, sizeof(int));
|
||||
length -= sizeof(int);
|
||||
fullread(s, v, length);
|
||||
|
||||
#ifdef T_SEND_TIME
|
||||
return new_event(t, type, length, v, d);
|
||||
#else
|
||||
return new_event(type, length, v, d);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void *gui_thread(void *_g)
|
||||
{
|
||||
gui *g = _g;
|
||||
@@ -167,6 +97,8 @@ int main(int n, char **v)
|
||||
|
||||
database = parse_database(database_filename);
|
||||
|
||||
store_config_file(database_filename);
|
||||
|
||||
number_of_events = number_of_ids(database);
|
||||
is_on = calloc(number_of_events, sizeof(int));
|
||||
if (is_on == NULL) abort();
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
void new_thread(void *(*f)(void *), void *data)
|
||||
{
|
||||
@@ -78,6 +80,51 @@ void socket_send(int socket, void *buffer, int size)
|
||||
}
|
||||
}
|
||||
|
||||
int get_connection(char *addr, int port)
|
||||
{
|
||||
struct sockaddr_in a;
|
||||
socklen_t alen;
|
||||
int s, t;
|
||||
|
||||
printf("waiting for connection on %s:%d\n", addr, port);
|
||||
|
||||
s = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s == -1) { perror("socket"); exit(1); }
|
||||
t = 1;
|
||||
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int)))
|
||||
{ perror("setsockopt"); exit(1); }
|
||||
|
||||
a.sin_family = AF_INET;
|
||||
a.sin_port = htons(port);
|
||||
a.sin_addr.s_addr = inet_addr(addr);
|
||||
|
||||
if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); }
|
||||
if (listen(s, 5)) { perror("bind"); exit(1); }
|
||||
alen = sizeof(a);
|
||||
t = accept(s, (struct sockaddr *)&a, &alen);
|
||||
if (t == -1) { perror("accept"); exit(1); }
|
||||
close(s);
|
||||
|
||||
printf("connected\n");
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
int fullread(int fd, void *_buf, int count)
|
||||
{
|
||||
char *buf = _buf;
|
||||
int ret = 0;
|
||||
int l;
|
||||
while (count) {
|
||||
l = read(fd, buf, count);
|
||||
if (l <= 0) { printf("read socket problem\n"); abort(); }
|
||||
count -= l;
|
||||
buf += l;
|
||||
ret += l;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* buffer */
|
||||
/****************************************************************************/
|
||||
|
||||
@@ -21,6 +21,8 @@ list *list_append(list *l, void *data);
|
||||
/****************************************************************************/
|
||||
|
||||
void socket_send(int socket, void *buffer, int size);
|
||||
int get_connection(char *addr, int port);
|
||||
int fullread(int fd, void *_buf, int count);
|
||||
|
||||
/****************************************************************************/
|
||||
/* buffer */
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include "database.h"
|
||||
#include "event.h"
|
||||
@@ -13,39 +11,10 @@
|
||||
#include "utils.h"
|
||||
#include "../T_defs.h"
|
||||
#include "event_selector.h"
|
||||
#include "config.h"
|
||||
|
||||
#define DEFAULT_REMOTE_PORT 2021
|
||||
|
||||
int get_connection(char *addr, int port)
|
||||
{
|
||||
struct sockaddr_in a;
|
||||
socklen_t alen;
|
||||
int s, t;
|
||||
|
||||
printf("waiting for connection on %s:%d\n", addr, port);
|
||||
|
||||
s = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s == -1) { perror("socket"); exit(1); }
|
||||
t = 1;
|
||||
if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &t, sizeof(int)))
|
||||
{ perror("setsockopt"); exit(1); }
|
||||
|
||||
a.sin_family = AF_INET;
|
||||
a.sin_port = htons(port);
|
||||
a.sin_addr.s_addr = inet_addr(addr);
|
||||
|
||||
if (bind(s, (struct sockaddr *)&a, sizeof(a))) { perror("bind"); exit(1); }
|
||||
if (listen(s, 5)) { perror("bind"); exit(1); }
|
||||
alen = sizeof(a);
|
||||
t = accept(s, (struct sockaddr *)&a, &alen);
|
||||
if (t == -1) { perror("accept"); exit(1); }
|
||||
close(s);
|
||||
|
||||
printf("connected\n");
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
printf(
|
||||
@@ -65,45 +34,6 @@ void usage(void)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int fullread(int fd, void *_buf, int count)
|
||||
{
|
||||
char *buf = _buf;
|
||||
int ret = 0;
|
||||
int l;
|
||||
while (count) {
|
||||
l = read(fd, buf, count);
|
||||
if (l <= 0) { printf("read socket problem\n"); abort(); }
|
||||
count -= l;
|
||||
buf += l;
|
||||
ret += l;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
event get_event(int s, char *v, void *d)
|
||||
{
|
||||
#ifdef T_SEND_TIME
|
||||
struct timespec t;
|
||||
#endif
|
||||
int type;
|
||||
int32_t length;
|
||||
|
||||
fullread(s, &length, 4);
|
||||
#ifdef T_SEND_TIME
|
||||
fullread(s, &t, sizeof(struct timespec));
|
||||
length -= sizeof(struct timespec);
|
||||
#endif
|
||||
fullread(s, &type, sizeof(int));
|
||||
length -= sizeof(int);
|
||||
fullread(s, v, length);
|
||||
|
||||
#ifdef T_SEND_TIME
|
||||
return new_event(t, type, length, v, d);
|
||||
#else
|
||||
return new_event(type, length, v, d);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void *gui_thread(void *_g)
|
||||
{
|
||||
gui *g = _g;
|
||||
@@ -199,6 +129,8 @@ int main(int n, char **v)
|
||||
|
||||
database = parse_database(database_filename);
|
||||
|
||||
store_config_file(database_filename);
|
||||
|
||||
number_of_events = number_of_ids(database);
|
||||
is_on = calloc(number_of_events, sizeof(int));
|
||||
if (is_on == NULL) abort();
|
||||
|
||||
Reference in New Issue
Block a user