Inspecting function arguments in GHCi

Andrew Kvapil viluon at seznam.cz
Mon Jan 25 13:18:13 UTC 2021


Dear Simon,

Thank you for the swift response. I did notice the lack of
comprehensive documentation on the details of the debugger. I keep
notes of my findings as I explore the codebase and expect to publish
them once I get them into a more presentable form. This work is a part
of my bachelor's thesis, so a fairly detailed explanation should come
out of it.

 > I'm not sure what you have in mind. Could you say more about (a) what 
you'd like
 > the user experience to be, and (b) how you are considering 
implementing it.

To be clear, I don't intend to affect the user experience of
breakpoints themselves. What I'm after is the information about thunks
collected at runtime without user intervention, I added what is
essentially a recreation of breakpoints called "tracepoints" for this
purpose. The user would simply invoke a traced program and information
about the strictness of various function applications would be logged
to a file. The result of the execution would be ultimately useful for
statistical analysis of the use of laziness in Haskell, although at
this point that is a distant and uncertain goal.

At the moment, the implementation of tracepoints suspends the GHCi
evaluation thread and immediately resumes it (by literally queueing
":continue" in the UI). To get any useful information and start
logging it at runtime, I need to capture more information than just
the free variables of an expression at bytecode generation time (or
sooner, since from what I gather this is in part also a responsibility
of the Tickish logic).

Perhaps the approach I've taken thus far is nonsensical or
significantly inferior to some well-known alternative I'm unaware of.
If that seems to be the case, I will happily listen to advice
suggesting a change of course. This is the first time I'm hacking on
GHC and I have to say I find the scale and complexity of the codebase
somewhat daunting, to say the least.

 > Perhaps you are suggesting that each breakpoint should capture 
bindings for
 > *all in-scope variables* rather than *all free variable of the 
sub-expression".
 > If so, that sounds pretty feasible.  It might risk keeping variables 
alive
 > that would otherwise have been garbage-collected, but maybe that's a 
price
 > worth paying.

Yes, not (necessarily) for breakpoints, but for tracepoints I think
that's closer to the desired behaviour. Perhaps there's even a simpler
approach that lets tracepoints only capture the "top-level" function
arguments, i.e. not the bindings that come from destructuring, as in
the shared qsort example. The top-level function arguments are what I
had in mind when suggesting the conversion to at-patterns.

Regards,
Andrew

On 25/01/2021 13:22, Simon Peyton Jones wrote:
 > Andrew
 >
 > We have very poor documentation of the inner workings of the entire 
breakpoint
 > and debugging mechanism.   And very few (zero?) people who truly 
understand it.
 >
 > You could do a great service by starting a Note or a wiki page or 
something
 > that lays out the moving parts.  You may not feel that you are well 
equipped to
 > do so, but you'd almost certainly improve matters!
 >
 > Has anyone else been working in this space.  Matthew P perhaps?
 >
 > |  So I'm wondering where would be a good place in the pipeline to
 > |  transform patterns like these into at-patterns, to give them Id's.
 >
 > I'm not sure what you have in mind. Could you say more about (a) what 
you'd like
 > the user experience to be, and (b) how you are considering 
implementing it.
 >
 > |  However, the breakpoint logic only looks at the free variables of the
 > |  right-hand sides and not transitively, which means that e.g. in the
 > |  following example neither ':print arg1' nor ':print as' works when the
 > |  interpreter hits a breakpoint in the top level expression on the RHS:
 >
 > Perhaps you are suggesting that each breakpoint should capture 
bindings for
 > *all in-scope variables* rather than *all free variable of the 
sub-expression".
 > If so, that sounds pretty feasible.  It might risk keeping variables 
alive
 > that would otherwise have been garbage-collected, but maybe that's a 
price
 > worth paying.
 >
 > Simon
 >
 >
 > |  -----Original Message-----
 > |  From: ghc-devs <ghc-devs-bounces at haskell.org> On Behalf Of Andrew
 > |  Kvapil
 > |  Sent: 25 January 2021 11:06
 > |  To: ghc-devs at haskell.org
 > |  Subject: Inspecting function arguments in GHCi
 > |
 > |  Hello,
 > |
 > |  I'm interested in inspecting the strictness of functions at runtime
 > |  and the depth of thunks "in the wild." For this reason I'm modifying
 > |  GHC 8.10.2, essentially to add additional information to breakpoints.
 > |  I'd like to reuse the logic behind GHCi's :print command
 > |  (pprintClosureCommand, obtainTermFromId, ...) for which I suppose I
 > |  need Id's. Those however don't exist for destructuring patterns, such
 > |  as those in the following equations:
 > |
 > |       last [x] = x
 > |       last (_:xs) = last xs
 > |
 > |  So I'm wondering where would be a good place in the pipeline to
 > |  transform patterns like these into at-patterns, to give them Id's.
 > |  However, the breakpoint logic only looks at the free variables of the
 > |  right-hand sides and not transitively, which means that e.g. in the
 > |  following example neither ':print arg1' nor ':print as' works when the
 > |  interpreter hits a breakpoint in the top level expression on the RHS:
 > |
 > |       qsort arg1@(a:as) = qsort left ++ [a] ++ qsort right
 > |         where (left, right) = (filter (<=a) as, filter (>a) as)
 > |
 > |  Thus I'd also like to know how to extend the free var logic for
 > |  Tickish that eventually leads to CgBreakInfo and :print's ability to
 > |  inspect these bindings at runtime. My goal would be to determine to
 > |  what extent was a thunk evaluated during function application.
 > |
 > |  Any advice would be greatly appreciated!
 > |
 > |  Regards,
 > |  Andrew Kvapil
 > |  _______________________________________________
 > |  ghc-devs mailing list
 > |  ghc-devs at haskell.org
 > |  https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Fmail.
 > |  haskell.org%2Fcgi-bin%2Fmailman%2Flistinfo%2Fghc-
 > |  devs&data=04%7C01%7Csimonpj%40microsoft.com%7C329b12ba7bb74a2657d2
 > |  08d8c1213bcc%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C0%7C637471695782
 > |  207814%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJ
 > |  BTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=uAi4NmjQLj3QG3B7ton5GeFDy
 > |  IWJecxtXoXiTIP11tE%3D&reserved=0
 >


More information about the ghc-devs mailing list