Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Start debugger when entering/returning from function #78

Open
ldeniau opened this issue Jan 9, 2023 · 4 comments
Open

Start debugger when entering/returning from function #78

ldeniau opened this issue Jan 9, 2023 · 4 comments

Comments

@ldeniau
Copy link

ldeniau commented Jan 9, 2023

I have tried to run the debugger at the entry of a function with the given name, using the following (slow) code. This works with debug.debug() but not with dbg(). Is there a recommended way to do this? Note that calling dbg() within debug.debug() does not work either (assuming dbg() is visible).

local dbg = require 'debugger'
local function dbgfun (fun, typ_)
  local function hook (event)
    local info = debug.getinfo(2,'n')
    if info.name == fun then
      io.write("dbg: ", info.name, "\n")
      return debug.debug() -- tail call
--    return dbg()         -- tail call
    end
  end
  debug.sethook(hook, typ_ or "call")
end
dbgfun("myfun")
@slembcke
Copy link
Owner

slembcke commented Jan 9, 2023

Hmm. Not sure off the top of my head, but I'm guessing it's because my debugger uses hooks internally and they conflict with yours. An alternative you can try is to patch the function instead. Something like this:

dbg = require 'debugger'

function dbgfun(fun, env)
	env = env or _G
	local f = env[fun]
	env[fun] = function(...)
		dbg()
		f(...)
	end
end

function dostuff()
	print("about to do stuff")
	local a = "" + 3 -- oops a bug
end

dbgfun("dostuff")

dostuff()

This should also be much much faster too as it doesn't leave a debug hook set all the time. Does that solve your problem, or do you need the hooks to work for some other reason?

@ldeniau
Copy link
Author

ldeniau commented Jan 10, 2023

I agree that your solution is fine for most cases and much faster than installing a hook triggered at each call, but it does not give access to local functions inside modules, which was my initial intention, and it's also tricky to wrap methods and metamethods with your approach. Wouldn't be possible to make your hooks compatible with the proposed approach, or to provide some dbgfun(funname, funline) working like a kind of breakpoint? Of course, this would assume that there is not much code to run between the set point and the hook.

I modified slightly your proposal to disable the wrap:

local function dbgfun (fun, env, f_)
  env = env or _G
  local f = assert(env[fun], "invalid function name or environment")
  env[fun] = f_ or function(...)
    dbg()
    f(...)
  end
  return f
end

@ldeniau
Copy link
Author

ldeniau commented Jan 10, 2023

update: calling dbg() within debug.debug() does not work because in fact debug.debug() does not work properly with my approach, i.e. running debug.traceback() does nothing. So I don't have a valid proposal for this problem.

@slembcke
Copy link
Owner

Wouldn't be possible to make your hooks compatible with the proposed approach, or to provide some dbgfun(funname, funline) working like a kind of breakpoint?

It might be possible, but I remember debug hooks having a bunch of limitations and just being painfully slow in general. I haven't touched that part of the code in a few years, so I don't know off the top of my head.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants