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

Print return stack on overflow #38

Closed
Varriount opened this issue Sep 14, 2021 · 4 comments
Closed

Print return stack on overflow #38

Varriount opened this issue Sep 14, 2021 · 4 comments

Comments

@Varriount
Copy link
Contributor

When NPeg throws a depth error due to an overflow in the return stack, it would be nice to have the exception contain a printout of the stack.

Something like

Error: unhandled exception: return stack overflow, depth>1024
Return stack:
sample.nim(10)             rule_name_one
keywords.nim(100)       rule_name_two
...

Rather than just

Error: unhandled exception: return stack overflow, depth>1024
@zevv
Copy link
Owner

zevv commented Nov 4, 2022

I poked around to see if I can make a proper implementation of this, but it's not trivial: the symbol table does not from survive compilation to run time, so there is no info available to generate a friendly stack trace at the time of the overflow.

I can make this work, but that will require keeping information around for longer then I'd like. Not sure of that is worth the effort at this time.

Any ideas on this?

@zevv
Copy link
Owner

zevv commented Nov 6, 2022

Hi @Varriount, I got a reasonable implementation for collecting and dumping a backtraces happening at NPeg parse time; its a available in the backtrace branch. It doesn't only handle retstack overflows, but any exception that is raised from NPeg, so both NPegException and any other exceptions as well.

The current implementation runs the parse fucntion in a try block; if an exception happens it will print the NPeg part of the stack and re-raise the original exception.

Ideally I would like to augment the original Nim stacktrace with the NPeg stackframes instead of just printing the trace, but I'm not sure if the current Nim infrastructure allows for this; NPeg would have to prepend its own backtrace to the Exceptions trace: seq[StackTraceEntry] fields, but these are not exported and I can't seem to find any other way to modify these. Maybe I should whip up a Nim PR for this.

Example:

import npeg                                                                                             
import std/strutils                                                           
import npeg                                                                
                                                       
const parser = peg("nodes", data: seq[string]):                                   
  nodes <- *(node * (' ' | !1))                  
  node <- extraWord | word                                                  
  extraWord <- word * extra * dash                                                  
  ident <- +Alpha                                     
  word <- ident:                                                        
    data.add($0)                                                                
  dash <- '-':                                                                   
    data.add($0)                                                                      
  extra <- number | dot              
  number <- +Digit:                                                                   
    raise newException(IOError, "IO failed")                                        
    data.add($0 & "(int)")                                               
  dot <- '.':                                                               
    data.add($0 & "(dot)")                                                         
                                                                                
var data: seq[string]                                                           
assert parser.match("a b1- c.", data).ok                                          
echo data 

Output:

/home/ico/sandbox/prjs/npeg/main.nim(30) main
/home/ico/sandbox/prjs/npeg/main.nim(27) flap
/home/ico/sandbox/prjs/npeg/src/npeg.nim(135) match
/home/ico/sandbox/prjs/npeg/src/npeg/patt.nim(90) fn`gensym46
/home/ico/sandbox/prjs/npeg/src/npeg/patt.nim(90) fn
/home/ico/sandbox/prjs/npeg/main.nim(11) nodes <- *(node * (' ' | !1))
/home/ico/sandbox/prjs/npeg/main.nim(12) node <- extraWord | word
/home/ico/sandbox/prjs/npeg/main.nim(13) extraWord <- word * extra * dash
/home/ico/sandbox/prjs/npeg/main.nim(19) extra <- number | dot
/home/ico/sandbox/prjs/npeg/main.nim(20) number <- +Digit

The last 5 lines show the NPeg part of the stacktrace including the regular lineInfo, with the NPeg rule appended for more clarity.

zevv added a commit that referenced this issue Nov 6, 2022
@zevv
Copy link
Owner

zevv commented Nov 6, 2022

let's see of nim-lang/Nim#20772 gets through, that will allow NPeg stack frames to go on the native Nim exception stack trace.

@zevv
Copy link
Owner

zevv commented Nov 6, 2022

For now, enable printing the stack trace with -d:npegStacktrace

zevv added a commit that referenced this issue Nov 7, 2022
zevv added a commit that referenced this issue Nov 7, 2022
zevv added a commit that referenced this issue Nov 7, 2022
zevv added a commit that referenced this issue Nov 7, 2022
zevv added a commit that referenced this issue Nov 7, 2022
zevv added a commit that referenced this issue Nov 7, 2022
zevv added a commit that referenced this issue Nov 7, 2022
zevv added a commit that referenced this issue Nov 7, 2022
zevv added a commit that referenced this issue Nov 7, 2022
@zevv zevv closed this as completed Nov 7, 2022
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