今天就介绍一下vs2013 下面调试libevent源码。不需要创建sln解决方案,只需要创建工程,包含
源码目录即可源码调试。
1、手工添加test/print-winsocke-errors.c文件,不然nmake编译的时候会报错。
print-winsock-errors.c源代码程序:
#include <winsock2.h>
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>
#include "event2/event.h"
#include "event2/util.h"
#include "event2/thread.h"
#define E(x) printf (#x " -> \"%s\"\n", evutil_socket_error_to_string (x));
int main (int argc, char **argv)
{
int i, j;
const char *s1, *s2;
#ifdef EVTHREAD_USE_WINDOWS_THREADS_IMPLEMENTED
evthread_use_windows_threads ();
#endif
s1 = evutil_socket_error_to_string (WSAEINTR);
for (i = 0; i < 3; i++) {
printf ("\niteration %d:\n\n", i);
E(WSAEINTR);
E(WSAEACCES);
E(WSAEFAULT);
E(WSAEINVAL);
E(WSAEMFILE);
E(WSAEWOULDBLOCK);
E(WSAEINPROGRESS);
E(WSAEALREADY);
E(WSAENOTSOCK);
E(WSAEDESTADDRREQ);
E(WSAEMSGSIZE);
E(WSAEPROTOTYPE);
E(WSAENOPROTOOPT);
E(WSAEPROTONOSUPPORT);
E(WSAESOCKTNOSUPPORT);
E(WSAEOPNOTSUPP);
E(WSAEPFNOSUPPORT);
E(WSAEAFNOSUPPORT);
E(WSAEADDRINUSE);
E(WSAEADDRNOTAVAIL);
E(WSAENETDOWN);
E(WSAENETUNREACH);
E(WSAENETRESET);
E(WSAECONNABORTED);
E(WSAECONNRESET);
E(WSAENOBUFS);
E(WSAEISCONN);
E(WSAENOTCONN);
E(WSAESHUTDOWN);
E(WSAETIMEDOUT);
E(WSAECONNREFUSED);
E(WSAEHOSTDOWN);
E(WSAEHOSTUNREACH);
E(WSAEPROCLIM);
E(WSASYSNOTREADY);
E(WSAVERNOTSUPPORTED);
E(WSANOTINITIALISED);
E(WSAEDISCON);
E(WSATYPE_NOT_FOUND);
E(WSAHOST_NOT_FOUND);
E(WSATRY_AGAIN);
E(WSANO_RECOVERY);
E(WSANO_DATA);
E(0xdeadbeef); /* test the case where no message is available */
/* fill up the hash table a bit to make sure it grows properly */
for (j = 0; j < 50; j++) {
int err;
evutil_secure_rng_get_bytes(&err, sizeof(err));
evutil_socket_error_to_string(err);
}
}
s2 = evutil_socket_error_to_string (WSAEINTR);
if (s1 != s2)
printf ("caching failed!\n");
libevent_global_shutdown ();
return EXIT_SUCCESS;
}
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跳入源码调试:
附上测试代码:
// libevent-test.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"wsock32.lib")
#pragma comment(lib,"libevent.lib")
#pragma comment(lib,"libevent_core.lib")
#pragma comment(lib,"libevent_extras.lib")
#include <sys/types.h>
#include <event2/event-config.h>
#include <sys/stat.h>
#ifndef _WIN32
#include <sys/queue.h>
#include <unistd.h>
#endif
#include <time.h>
#ifdef EVENT__HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <event2/event.h>
#include <event2/event_struct.h>
#include <event2/util.h>
#ifdef _WIN32
#include <winsock2.h>
#endif
struct timeval lasttime;
int event_is_persistent;
static void
timeout_cb(evutil_socket_t fd, short event, void *arg)
{
struct timeval newtime, difference;
struct event *timeout = (struct event *)arg;
double elapsed;
evutil_gettimeofday(&newtime, NULL);
evutil_timersub(&newtime, &lasttime, &difference);
elapsed = difference.tv_sec +
(difference.tv_usec / 1.0e6);
printf("timeout_cb called at %d: %.3f seconds elapsed.\n",
(int)newtime.tv_sec, elapsed);
lasttime = newtime;
if (!event_is_persistent) {
struct timeval tv;
evutil_timerclear(&tv);
tv.tv_sec = 2;
event_add(timeout, &tv);
}
}
int
main(int argc, char **argv)
{
struct event timeout;
struct timeval tv;
struct event_base *base;
int flags;
#ifdef _WIN32
WORD wVersionRequested;
WSADATA wsaData;
wVersionRequested = MAKEWORD(2, 2);
(void)WSAStartup(wVersionRequested, &wsaData);
#endif
if (argc == 2 && !strcmp(argv[1], "-p")) {
event_is_persistent = 1;
flags = EV_PERSIST;
}
else {
event_is_persistent = 0;
flags = 0;
}
/* Initalize the event library */
base = event_base_new();
/* Initalize one event */
event_assign(&timeout, base, -1, flags, timeout_cb, (void*)&timeout);
evutil_timerclear(&tv);
tv.tv_sec = 2;
event_add(&timeout, &tv);
evutil_gettimeofday(&lasttime, NULL);
event_base_dispatch(base);
return (0);
}