VisuaGDB 编译、调试libev
2017-07-23 16:52
666 查看
由于在Linux下阅读、调试libev源码过于复杂繁琐,需要为vim或emacs做配置一堆配置,才稍微好些,但是操作起来十分困难,花费大量的时间,影响阅读和理解libev的速度。所以使用VisualGDB编译、调试libev。
VS2013
Ubuntu 16.04 server 虚拟机
win 7操作系统
地址:https://github.com/quartzjer/libev
在Linux下编译libev
1.执行./configure 命令
2.执行make命令。从编译输出可以看到执行make的时候,只是编译了ev.c、event.c 两个文件
在window中创建Visual gdb项目
参考网址:http://blog.csdn.net/wu936754331/article/details/49305377
拷贝libev中的文件到Visual gdb项目中
将.c、.h文件拷贝到Visual gdb项目中
添加libev文件并编译运行
只添加ev.c、event.c和头文件,并创建main.c文件,并粘贴一下demo代码,然后编译运行。如果添加了其他的.c文件,编译会报错,因为ev_epoll.c ev_kqueue.c ev_poll.c ev_port.c ev_select.c ev_win32.c这个几个源文件没有.h文件的,它们被ev.c event.c直接include 插入到源码中,若再次添加就会产生编译报错。如果想更好地阅读源码,直接将源码插入到include .c文件处
编译环境
Visual gdb 5.0VS2013
Ubuntu 16.04 server 虚拟机
安装gcc、g++、gdb、open-ssh
win 7操作系统
编译步骤
下载libev到Ubuntu Linux地址:https://github.com/quartzjer/libev
在Linux下编译libev
1.执行./configure 命令
2.执行make命令。从编译输出可以看到执行make的时候,只是编译了ev.c、event.c 两个文件
在window中创建Visual gdb项目
参考网址:http://blog.csdn.net/wu936754331/article/details/49305377
拷贝libev中的文件到Visual gdb项目中
将.c、.h文件拷贝到Visual gdb项目中
添加libev文件并编译运行
只添加ev.c、event.c和头文件,并创建main.c文件,并粘贴一下demo代码,然后编译运行。如果添加了其他的.c文件,编译会报错,因为ev_epoll.c ev_kqueue.c ev_poll.c ev_port.c ev_select.c ev_win32.c这个几个源文件没有.h文件的,它们被ev.c event.c直接include 插入到源码中,若再次添加就会产生编译报错。如果想更好地阅读源码,直接将源码插入到include .c文件处
// a single header file is required #include <stdio.h> // for puts #include <stdio.h> #include <netinet/in.h> #include <errno.h> #include "ev.h" #define MAXLEN 1023 #define PORT 1200 #define ADDR_IP "192.168.1.112" int socket_init(); void accept_callback(struct ev_loop *loop, ev_io *w, int revents); void recv_callback(struct ev_loop *loop, ev_io *w, int revents); void write_callback(struct ev_loop *loop, ev_io *w, int revents); int main(int argc, char** argv) { int listen; ev_io ev_io_watcher; listen = socket_init(); struct ev_loop *loop = ev_loop_new(EVBACKEND_EPOLL); ev_io_init(&ev_io_watcher, accept_callback, listen, EV_READ); ev_io_start(loop, &ev_io_watcher); ev_loop(loop, 0); ev_loop_destroy(loop); return 0; } int socket_init() { struct sockaddr_in my_addr; int listener; if ((listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("socket"); exit(1); } else { printf("SOCKET CREATE SUCCESS!\n"); } //setnonblocking(listener); int so_reuseaddr = 1; setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &so_reuseaddr, sizeof(so_reuseaddr)); bzero(&my_addr, sizeof(my_addr)); my_addr.sin_family = PF_INET; my_addr.sin_port = htons(PORT); my_addr.sin_addr.s_addr = inet_addr(ADDR_IP); if (bind(listener, (struct sockaddr *) &my_addr, sizeof(struct sockaddr)) == -1) { perror("bind error!\n"); exit(1); } else { printf("IP BIND SUCCESS,IP:%s\n", ADDR_IP); } if (listen(listener, 1024) == -1) { perror("listen error!\n"); exit(1); } else { printf("LISTEN SUCCESS,PORT:%d\n", PORT); } return listener; } void accept_callback(struct ev_loop *loop, ev_io *w, int revents) { int newfd; struct sockaddr_in sin; socklen_t addrlen = sizeof(struct sockaddr); ev_io* accept_watcher = malloc(sizeof(ev_io)); while ((newfd = accept(w->fd, (struct sockaddr *)&sin, &addrlen)) < 0) { if (errno == EAGAIN || errno == EWOULDBLOCK) { //these are transient, so don't log anything. continue; } else { printf("accept error.[%s]\n", strerror(errno)); break; } } ev_io_init(accept_watcher, recv_callback, newfd, EV_READ); ev_io_start(loop, accept_watcher); printf("accept callback : fd :%d\n", accept_watcher->fd); } void recv_callback(struct ev_loop *loop, ev_io *w, int revents) { char buffer[1024] = { 0 }; int ret = 0; //ev_io write_event; loop: ret = recv(w->fd, buffer, MAXLEN, 0); if (ret > 0) { printf("recv message :%s \n", buffer); } else if (ret == 0) { printf("remote socket closed!socket fd: %d\n", w->fd); close(w->fd); ev_io_stop(loop, w); free(w); return; } else { if (errno == EAGAIN || errno == EWOULDBLOCK) { goto loop; } else { printf("ret :%d ,close socket fd : %d\n", ret, w->fd); close(w->fd); ev_io_stop(loop, w); free(w); return; } } int fd = w->fd; ev_io_stop(loop, w); ev_io_init(w, write_callback, fd, EV_WRITE); ev_io_start(loop, w); printf("socket fd : %d, turn read 2 write loop! ", fd); } void write_callback(struct ev_loop *loop, ev_io *w, int revents) { char buffer[1024] = { 0 }; //ev_io read_event; snprintf(buffer, 1023, "this is a libev server!\n"); write(w->fd, buffer, strlen(buffer), 0); int fd = w->fd; ev_io_stop(loop, w); ev_io_init(w, recv_callback, fd, EV_READ); ev_io_start(loop, w); }
相关文章推荐
- Emacs GCC GDB 编译调试方法
- 使用VS+VisualGDB编译调试Linux程序
- 如何在Windows的命令行下进行程序编译和gdb调试
- 用Eclipse和GDB构建ARM交叉编译和在线调试环境
- CMake编译时支持GDB调试
- 使用gcc -g编译,gdb调试时仍然存在“no debug symbols found”的错误
- vlc编译:用GDB调试vlc
- 交叉编译和交叉调试环境搭建及---环境变量使用----及GDB安装
- Linux学习(十二):gcc编译和gdb调试
- 用Eclipse和GDB构建ARM交叉编译和在线调试环境
- 用Eclipse和GDB构建ARM交叉编译和在线调试环境
- 编译安装gdb+insight和gdbserver远程调试
- gcc编译与gdb调试简要步骤
- VS+VisualGDB编译调试Linux程序
- arm-linux-gdb调试工具的安装与交叉编译gdbserver
- 交叉编译gdb+gdbserver实现远程调试
- Linux GCC编译、gdb调试、makefile、动态链接库的创建
- c++求教:我在linux下用CodeLite编译调试时出现&"warning: GDB: Failed to set controlling terminal: Operation not permitted/n"
- QEMU+GDB 安装编译调试linux内核
- 编译arm-linux-gdb和远程调试arm板程序