implicit call stacks and calling function

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

implicit call stacks and calling function

Evan Laforge
I noticed this when I started using the new implicit call stacks
feature.  I didn't bring it up because I figure it probably had a good
reason and was too late to change anyway, but the recent talk about
HasCallStack reminded me and I'm curious.

When you do GHC.Stack.getCallStack you get a [(String, SrcPos)].  The
SrcPos is the position of the calling function, but the String is the
callee function.  So you can't get the name of the calling function.
Instead, you get the name of the function with the call stack
annotation.  That's not so useful because in say a logging function,
I'm interested in the caller's name.  I don't need the name of the
logging function, it's just something boring like "info" or "warn"!

When I switched from a custom preprocessor that sort of implemented
SRCLOC_ANNOTATE, it was definitely nice to lose the custom local
hackery, but not so nice to lose the caller's name.  For tests I used
an unsafe mutable global via unsafePerformIO, otherwise failed tests
can't report the name of the failing test, but the hack doesn't work
for logging.

Is there a reason it was done the way it was, or a way to get the name
of the calling function?
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: implicit call stacks and calling function

Eric Seidel-3
On Mon, Mar 7, 2016, at 11:35, Evan Laforge wrote:

> When you do GHC.Stack.getCallStack you get a [(String, SrcPos)].  The
> SrcPos is the position of the calling function, but the String is the
> callee function.  So you can't get the name of the calling function.
> Instead, you get the name of the function with the call stack
> annotation.  That's not so useful because in say a logging function,
> I'm interested in the caller's name.  I don't need the name of the
> logging function, it's just something boring like "info" or "warn"!
>
> Is there a reason it was done the way it was, or a way to get the name
> of the calling function?

The reason we provide the name of the callee is that the standard format
for a stack trace is callee+pos :)

You point about wanting the caller's name too is well-taken though. In
most languages you can just look at the next item in the stack to grab
the caller, but with HasCallStack there may be no next item... I doubt
it would be hard to add the caller's name too, I'd be happy to look into
it post-ICFP. Would you mind filing a ticket?

Eric
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: implicit call stacks and calling function

Evan Laforge
On Mon, Mar 7, 2016 at 11:46 AM, Eric Seidel <[hidden email]> wrote:
> The reason we provide the name of the callee is that the standard format
> for a stack trace is callee+pos :)

I guess it depends how you look at it.  I'm used to caller + pos, e.g. in Java:

java.lang.RuntimeException: blah blah
at com...Caller.caller(Caller.java:494)
at ...

Or python:

Traceback (most recent call last):
  File "t.py", line 2, in caller
    def caller(): callee()
  File "t.py", line 1, in callee
    def callee(): 1/0
ZeroDivisionError: integer division or modulo by zero

The haskell version (reversed to match python) would be like:

File "Caller.hs", line 6, in callee
    caller = callee 10
File "Caller.hs", line 9, in ?stack
    callee _n = mapM_ print (Stack.getCallStack ?stack)

To me this seems off by one, line 6 is in 'caller', not 'callee'.

> You point about wanting the caller's name too is well-taken though. In
> most languages you can just look at the next item in the stack to grab
> the caller, but with HasCallStack there may be no next item... I doubt
> it would be hard to add the caller's name too, I'd be happy to look into
> it post-ICFP. Would you mind filing a ticket?

Done: https://ghc.haskell.org/trac/ghc/ticket/11686

In it I suggested adding a Stack.getFrames :: [Stack.Frame], Frame
could then have callee and srcloc fields as per getCallStack's pairs,
and add a caller field.  Just a suggestion.

Thanks so much!
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Reply | Threaded
Open this post in threaded view
|

Re: implicit call stacks and calling function

Eric Seidel-3
On Mon, Mar 7, 2016, at 15:36, Evan Laforge wrote:

> On Mon, Mar 7, 2016 at 11:46 AM, Eric Seidel <[hidden email]> wrote:
> > The reason we provide the name of the callee is that the standard format
> > for a stack trace is callee+pos :)
>
> I guess it depends how you look at it.  I'm used to caller + pos, e.g. in
> Java:
>
> java.lang.RuntimeException: blah blah
> at com...Caller.caller(Caller.java:494)
> at ...
>
> Or python:
>
> Traceback (most recent call last):
>   File "t.py", line 2, in caller
>     def caller(): callee()
>   File "t.py", line 1, in callee
>     def callee(): 1/0
> ZeroDivisionError: integer division or modulo by zero
>
> The haskell version (reversed to match python) would be like:
>
> File "Caller.hs", line 6, in callee
>     caller = callee 10
> File "Caller.hs", line 9, in ?stack
>     callee _n = mapM_ print (Stack.getCallStack ?stack)
>
> To me this seems off by one, line 6 is in 'caller', not 'callee'.

Huh, you're quite right.. I remember checking python's formatting when I
originally implemented the feature but I must have misread the stack..
_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe