static int profiler_init(lua_State *L) { lprofP_STATE* S; const char* outfile; float function_call_time; lua_pushlightuserdata(L, &profstate_id); lua_gettable(L, LUA_REGISTRYINDEX); if(!lua_isnil(L, -1)) { profiler_stop(L); } lua_pop(L, 1); function_call_time = calcCallTime(L); outfile = NULL; if(lua_gettop(L) >= 1) outfile = luaL_checkstring(L, 1); /* init with default file name and printing a header line */ if (!(S=lprofP_init_core_profiler(outfile, 1, function_call_time))) { return luaL_error(L,"LuaProfiler error: output file could not be opened!"); } lua_sethook(L, (lua_Hook)callhook, LUA_MASKCALL | LUA_MASKRET, 0); lua_pushlightuserdata(L, &profstate_id); lua_pushlightuserdata(L, S); lua_settable(L, LUA_REGISTRYINDEX); /* use our own exit function instead */ lua_getglobal(L, "os"); lua_pushlightuserdata(L, &exit_id); lua_pushstring(L, "exit"); lua_gettable(L, -3); lua_settable(L, LUA_REGISTRYINDEX); lua_pushstring(L, "exit"); lua_pushcfunction(L, (lua_CFunction)exit_profiler); lua_settable(L, -3); #if 0 /* use our own coroutine.create function instead */ lua_getglobal(L, "coroutine"); lua_pushstring(L, "create"); lua_pushcfunction(L, (lua_CFunction)coroutine_create); lua_settable(L, -3); #endif /* the following statement is to simulate how the execution stack is */ /* supposed to be by the time the profiler is activated when loaded */ /* as a library. */ lprofP_callhookIN(S, "profiler_init", "(C)", -1, -1); lua_pushboolean(L, 1); return 1; }
static int profiler_init(lua_State *L) { lprofP_STATE* S; const char* outfile; float function_call_time; function_call_time = calcCallTime(L); outfile = NULL; if(lua_gettop(L) == 1) outfile = luaL_checkstring(L, -1); lua_sethook(L, (lua_Hook)callhook, LUA_MASKCALL | LUA_MASKRET, 0); /* init with default file name and printing a header line */ if (!(S=lprofP_init_core_profiler(outfile, 1, function_call_time))) { luaL_error(L,"LuaProfiler error: output file could not be opened!"); lua_pushnil(L); return 1; } /* Richard 30 May 2007 * add one to L when used as a key, otherwise this causes the * thread to be garbage collected. A bug in the lua GC? */ lua_pushlightuserdata(L, ((unsigned int)L) + 1); lua_pushlightuserdata(L, S); lua_settable(L, LUA_REGISTRYINDEX); /* use our own exit function instead */ lua_getglobal(L, "os"); lua_pushlightuserdata(L, &exit_id); lua_pushstring(L, "exit"); lua_gettable(L, -3); lua_settable(L, LUA_REGISTRYINDEX); lua_pushstring(L, "exit"); lua_pushcfunction(L, (lua_CFunction)exit_profiler); lua_settable(L, -3); /* use our own coroutine.create function instead */ /* lua_getglobal(L, "coroutine");*/ /* lua_pushstring(L, "create");*/ /* lua_pushcfunction(L, (lua_CFunction)coroutine_create);*/ /* lua_settable(L, -3);*/ /* the following statement is to simulate how the execution stack is */ /* supposed to be by the time the profiler is activated when loaded */ /* as a library. */ lprofP_callhookIN(S, "", "profiler_init", "(C)", -1, -1); lua_pushboolean(L, 1); return 1; }
// 注册hook事件,生成log文件,并把当前profile状态压入registry表 int profiler_init(lua_State *L) { lua_getglobal(L, GLOBALSTATE_NAME); //如果不为nil,则证明是多次init了,这时候我们先stop上一次的,在启动新的 if(!lua_isnil(L, -1)) { profiler_stop(L); } lua_pop(L, 1); // 初始化全局变量 GlobalState* pGlobalState = (GlobalState*)malloc(sizeof(GlobalState)); lua_pushlightuserdata(L, pGlobalState); lua_setglobal(L, GLOBALSTATE_NAME); pGlobalState->BufCount = 0; pGlobalState->Buffer = (BufferData*)malloc(sizeof(BufferData) * MAX_BUFFER_COUNT); ProfState *S; const char* OutFile; pGlobalState->FuncCallTime = calcCallTime(L); OutFile = NULL; if (lua_gettop(L) == 1) OutFile = luaL_checkstring(L, -1); // 因为start有一个输出文件名的可选参数 lua_sethook(L, (lua_Hook)CallHook, LUA_MASKCALL | LUA_MASKRET, 0); pGlobalState->HookMark = 1; if (!(S=InitCoreProfiler(OutFile, 1, pGlobalState))) // 生成log文件,并输出首行信息,返回初始化成员的S { luaL_error(L, "LuaProfiler error: output file could not be opened!"); lua_pushnil(L); return 0; } // 输出键值对,把生成表存储在以LUA_REGISTRYINDEX为假索引的registry表(栈)中 lua_pushlightuserdata(L, &StateID); lua_pushlightuserdata(L, S); lua_settable(L, LUA_REGISTRYINDEX); CallHookIn(S, "start", "(C)", -1, -1); lua_pushboolean(L, 1); // 为后面的检测提供依据 return 1; }