自己内功的提升,无非是向前辈学习和修炼自身,对于编码也是如此,学习优秀的库只有从
源代码学起,才能深刻理解库实现的来龙去脉,加深自己的理解,提升自己的功力。
今天就介绍一下vs2013 下面调试libevent源码。不需要创建sln解决方案,只需要创建工程,包含
源码目录即可源码调试。
1、手工添加print-winsocke-errors.c文件,不然nmake编译的时候会报错。
print-winsocke-errors.c源代码程序:
1 #include <winsock2.h> 2 #include <windows.h> 3 4 #include <stdlib.h> 5 #include <stdio.h> 6 7 #include "event2/event.h" 8 #include "event2/util.h" 9 #include "event2/thread.h" 10 11 #define E(x) printf (#x " -> "%s" ", evutil_socket_error_to_string (x)); 12 13 int main (int argc, char **argv) 14 { 15 int i, j; 16 const char *s1, *s2; 17 18 #ifdef EVTHREAD_USE_WINDOWS_THREADS_IMPLEMENTED 19 evthread_use_windows_threads (); 20 #endif 21 22 s1 = evutil_socket_error_to_string (WSAEINTR); 23 24 for (i = 0; i < 3; i++) { 25 printf (" iteration %d: ", i); 26 E(WSAEINTR); 27 E(WSAEACCES); 28 E(WSAEFAULT); 29 E(WSAEINVAL); 30 E(WSAEMFILE); 31 E(WSAEWOULDBLOCK); 32 E(WSAEINPROGRESS); 33 E(WSAEALREADY); 34 E(WSAENOTSOCK); 35 E(WSAEDESTADDRREQ); 36 E(WSAEMSGSIZE); 37 E(WSAEPROTOTYPE); 38 E(WSAENOPROTOOPT); 39 E(WSAEPROTONOSUPPORT); 40 E(WSAESOCKTNOSUPPORT); 41 E(WSAEOPNOTSUPP); 42 E(WSAEPFNOSUPPORT); 43 E(WSAEAFNOSUPPORT); 44 E(WSAEADDRINUSE); 45 E(WSAEADDRNOTAVAIL); 46 E(WSAENETDOWN); 47 E(WSAENETUNREACH); 48 E(WSAENETRESET); 49 E(WSAECONNABORTED); 50 E(WSAECONNRESET); 51 E(WSAENOBUFS); 52 E(WSAEISCONN); 53 E(WSAENOTCONN); 54 E(WSAESHUTDOWN); 55 E(WSAETIMEDOUT); 56 E(WSAECONNREFUSED); 57 E(WSAEHOSTDOWN); 58 E(WSAEHOSTUNREACH); 59 E(WSAEPROCLIM); 60 E(WSASYSNOTREADY); 61 E(WSAVERNOTSUPPORTED); 62 E(WSANOTINITIALISED); 63 E(WSAEDISCON); 64 E(WSATYPE_NOT_FOUND); 65 E(WSAHOST_NOT_FOUND); 66 E(WSATRY_AGAIN); 67 E(WSANO_RECOVERY); 68 E(WSANO_DATA); 69 E(0xdeadbeef); /* test the case where no message is available */ 70 71 /* fill up the hash table a bit to make sure it grows properly */ 72 for (j = 0; j < 50; j++) { 73 int err; 74 evutil_secure_rng_get_bytes(&err, sizeof(err)); 75 evutil_socket_error_to_string(err); 76 } 77 } 78 79 s2 = evutil_socket_error_to_string (WSAEINTR); 80 if (s1 != s2) 81 printf ("caching failed! "); 82 83 libevent_global_shutdown (); 84 85 return EXIT_SUCCESS; 86 }
2、修改Makefile.nmake
将
CFLAGS=$(CFLAGS) /Ox /W3 /wd4996 /nologo
改为
CFLAGS=$(CFLAGS) /Od /W3 /wd4996 /nologo /Zi
使用/Od禁止优化,使用/Zi 生成调试信息。
3、vs2013命令行编译:nmake /f Makefile.nmake
编译生成:
4、新建工程,附加源码调试
解决方案包含源代码目录:
以上三个目录添加到VC的附加库目录。
lib包含目录添加刚才生成的
所在目录
5、源码跟踪调试
F11跳入源码调试:
附上测试代码:
1 // libevent-test.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 6 #pragma comment(lib,"ws2_32.lib") 7 #pragma comment(lib,"wsock32.lib") 8 #pragma comment(lib,"libevent.lib") 9 #pragma comment(lib,"libevent_core.lib") 10 #pragma comment(lib,"libevent_extras.lib") 11 12 13 14 #include <sys/types.h> 15 16 #include <event2/event-config.h> 17 18 #include <sys/stat.h> 19 #ifndef _WIN32 20 #include <sys/queue.h> 21 #include <unistd.h> 22 #endif 23 #include <time.h> 24 #ifdef EVENT__HAVE_SYS_TIME_H 25 #include <sys/time.h> 26 #endif 27 #include <fcntl.h> 28 #include <stdlib.h> 29 #include <stdio.h> 30 #include <string.h> 31 #include <errno.h> 32 33 #include <event2/event.h> 34 #include <event2/event_struct.h> 35 #include <event2/util.h> 36 37 #ifdef _WIN32 38 #include <winsock2.h> 39 #endif 40 41 struct timeval lasttime; 42 43 int event_is_persistent; 44 45 static void 46 timeout_cb(evutil_socket_t fd, short event, void *arg) 47 { 48 struct timeval newtime, difference; 49 struct event *timeout = (struct event *)arg; 50 double elapsed; 51 52 evutil_gettimeofday(&newtime, NULL); 53 evutil_timersub(&newtime, &lasttime, &difference); 54 elapsed = difference.tv_sec + 55 (difference.tv_usec / 1.0e6); 56 57 printf("timeout_cb called at %d: %.3f seconds elapsed. ", 58 (int)newtime.tv_sec, elapsed); 59 lasttime = newtime; 60 61 if (!event_is_persistent) { 62 struct timeval tv; 63 evutil_timerclear(&tv); 64 tv.tv_sec = 2; 65 event_add(timeout, &tv); 66 } 67 } 68 69 int 70 main(int argc, char **argv) 71 { 72 struct event timeout; 73 struct timeval tv; 74 struct event_base *base; 75 int flags; 76 77 #ifdef _WIN32 78 WORD wVersionRequested; 79 WSADATA wsaData; 80 81 wVersionRequested = MAKEWORD(2, 2); 82 83 (void)WSAStartup(wVersionRequested, &wsaData); 84 #endif 85 86 if (argc == 2 && !strcmp(argv[1], "-p")) { 87 event_is_persistent = 1; 88 flags = EV_PERSIST; 89 } 90 else { 91 event_is_persistent = 0; 92 flags = 0; 93 } 94 95 /* Initalize the event library */ 96 base = event_base_new(); 97 98 /* Initalize one event */ 99 event_assign(&timeout, base, -1, flags, timeout_cb, (void*)&timeout); 100 101 evutil_timerclear(&tv); 102 tv.tv_sec = 2; 103 event_add(&timeout, &tv); 104 105 evutil_gettimeofday(&lasttime, NULL); 106 107 event_base_dispatch(base); 108 109 return (0); 110 }
以上就是vs2013下的源码跟踪调试,下面就开始对libevent深入学习了。
如有转载,请注明出处。