support nimStackTraceOverride (#181)

This commit is contained in:
Ștefan Talpalaru 2021-05-06 09:49:55 +02:00 committed by GitHub
parent 43b8aada20
commit c15c985c1f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 68 additions and 46 deletions

View File

@ -30,7 +30,8 @@ install:
build_script:
- cd C:\projects\%APPVEYOR_PROJECT_SLUG%
- nimble install -y
- nimble install -y --depsOnly
- nimble install -y libbacktrace
test_script:
- nimble test

View File

@ -11,19 +11,14 @@ jobs:
target:
- os: linux
cpu: amd64
TEST_LANG: c
- os: linux
cpu: i386
TEST_LANG: c
- os: macos
cpu: amd64
TEST_LANG: c
- os: windows
cpu: amd64
TEST_LANG: c
- os: windows
cpu: i386
TEST_LANG: c
include:
- target:
os: linux
@ -35,7 +30,7 @@ jobs:
os: windows
builder: windows-2019
name: '${{ matrix.target.os }}-${{ matrix.target.cpu }}-${{ matrix.target.TEST_LANG }} (${{ matrix.branch }})'
name: '${{ matrix.target.os }}-${{ matrix.target.cpu }} (${{ matrix.branch }})'
runs-on: ${{ matrix.builder }}
steps:
- name: Checkout nim-chronos
@ -130,8 +125,8 @@ jobs:
id: nim-cache
uses: actions/cache@v2
with:
path: nim
key: 'nim-${{ matrix.target.os }}-${{ matrix.target.cpu }}-${{ steps.versions.outputs.nimbus_build_system }}'
path: NimBinaries
key: 'nim-${{ matrix.target.os }}-${{ matrix.target.cpu }}-${{ steps.versions.outputs.nimbus_build_system }}-2'
- name: Build Nim and associated tools
if: steps.nim-cache.outputs.cache-hit != 'true'
@ -150,15 +145,6 @@ jobs:
fi
env MAKE="$MAKE_CMD -j2" ARCH_OVERRIDE=$PLATFORM CC=gcc bash build_nim.sh nim csources dist/nimble NimBinaries
# clean up to save cache space
cd nim
rm koch
rm -rf nimcache
rm -rf csources
rm -rf tests
rm -rf dist
rm -rf .git
- name: Setup environment
shell: bash
run: echo '${{ github.workspace }}/nim/bin' >> $GITHUB_PATH
@ -168,4 +154,5 @@ jobs:
working-directory: nim-chronos
run: |
nimble install -y --depsOnly
env TEST_LANG="${{ matrix.target.TEST_LANG }}" nimble test
nimble install -y libbacktrace
nimble test

View File

@ -14,17 +14,22 @@ requires "nim > 1.2.0",
"https://github.com/status-im/nim-unittest2.git#head"
task test, "Run all tests":
var commands = @[
"nim c -r -d:useSysAssert -d:useGcAssert tests/",
"nim c -r -d:chronosStackTrace -d:chronosStrictException tests/",
"nim c -r -d:release tests/",
"nim c -r -d:release -d:chronosFutureTracking tests/"
]
var
commandStart = "nim c -r --hints:off --verbosity:0 --skipParentCfg:on --warning[ObservableStores]:off"
commands = @[
commandStart & " -d:useSysAssert -d:useGcAssert tests/",
commandStart & " -d:chronosStackTrace -d:chronosStrictException tests/",
commandStart & " -d:release tests/",
commandStart & " -d:release -d:chronosFutureTracking tests/",
commandStart & " -d:release --debugger:native -d:chronosStackTrace -d:nimStackTraceOverride --import:libbacktrace tests/",
]
when (NimMajor, NimMinor) >= (1, 5):
commands.add "nim c -r --gc:orc -d:chronosFutureTracking -d:release -d:chronosStackTrace tests/"
commands.add commandStart & " --gc:orc -d:chronosFutureTracking -d:release -d:chronosStackTrace tests/"
for testname in ["testall"]:
for cmd in commands:
let curcmd = cmd & testname
echo "\n" & curcmd
exec curcmd
rmFile "tests/" & testname

View File

@ -1,8 +1,8 @@
#
# Chronos
#
# (c) Copyright 2015 Dominik Picheta
# (c) Copyright 2018-Present Status Research & Development GmbH
# (c) Copyright 2015 Dominik Picheta
# (c) Copyright 2018-2021 Status Research & Development GmbH
#
# Licensed under either of
# Apache License, version 2.0, (LICENSE-APACHEv2)
@ -12,6 +12,13 @@ import std/[os, tables, strutils, heapqueue, options, deques, cstrutils, sequtil
import ./srcloc
export srcloc
when defined(nimHasStacktracesModule):
import system/stacktraces
else:
const
reraisedFromBegin = -10
reraisedFromEnd = -100
const
LocCreateIndex* = 0
LocCompleteIndex* = 1
@ -390,49 +397,71 @@ proc `cancelCallback=`*[T](future: Future[T], cb: CallbackFunc) =
## This callback will be called immediately as ``future.cancel()`` invoked.
future.cancelcb = cb
template getFilenameProcname(entry: StackTraceEntry): (string, string) =
when compiles(entry.filenameStr) and compiles(entry.procnameStr):
# We can't rely on "entry.filename" and "entry.procname" still being valid
# cstring pointers, because the "string.data" buffers they pointed to might
# be already garbage collected (this entry being a non-shallow copy,
# "entry.filename" no longer points to "entry.filenameStr.data", but to the
# buffer of the original object).
(entry.filenameStr, entry.procnameStr)
else:
($entry.filename, $entry.procname)
proc getHint(entry: StackTraceEntry): string =
## We try to provide some hints about stack trace entries that the user
## may not be familiar with, in particular calls inside the stdlib.
result = ""
if entry.procname == "processPendingCallbacks":
if cmpIgnoreStyle(entry.filename, "asyncdispatch.nim") == 0:
let (filename, procname) = getFilenameProcname(entry)
if procname == "processPendingCallbacks":
if cmpIgnoreStyle(filename, "asyncdispatch.nim") == 0:
return "Executes pending callbacks"
elif entry.procname == "poll":
if cmpIgnoreStyle(entry.filename, "asyncdispatch.nim") == 0:
elif procname == "poll":
if cmpIgnoreStyle(filename, "asyncdispatch.nim") == 0:
return "Processes asynchronous completion events"
if entry.procname.endsWith("_continue"):
if cmpIgnoreStyle(entry.filename, "asyncmacro.nim") == 0:
if procname.endsWith("_continue"):
if cmpIgnoreStyle(filename, "asyncmacro.nim") == 0:
return "Resumes an async procedure"
proc `$`*(entries: seq[StackTraceEntry]): string =
proc `$`(stackTraceEntries: seq[StackTraceEntry]): string =
try:
when defined(nimStackTraceOverride) and declared(addDebuggingInfo):
let entries = addDebuggingInfo(stackTraceEntries)
else:
let entries = stackTraceEntries
# Find longest filename & line number combo for alignment purposes.
var longestLeft = 0
for entry in entries:
if isNil(entry.procName): continue
let (filename, procname) = getFilenameProcname(entry)
let left = $entry.filename & $entry.line
if left.len > longestLeft:
longestLeft = left.len
if procname == "": continue
let leftLen = filename.len + len($entry.line)
if leftLen > longestLeft:
longestLeft = leftLen
var indent = 2
# Format the entries.
for entry in entries:
if isNil(entry.procName):
if entry.line == -10:
let (filename, procname) = getFilenameProcname(entry)
if procname == "":
if entry.line == reraisedFromBegin:
result.add(spaces(indent) & "#[\n")
indent.inc(2)
else:
elif entry.line == reraisedFromEnd:
indent.dec(2)
result.add(spaces(indent) & "]#\n")
continue
let left = "$#($#)" % [$entry.filename, $entry.line]
let left = "$#($#)" % [filename, $entry.line]
result.add((spaces(indent) & "$#$# $#\n") % [
left,
spaces(longestLeft - left.len + 2),
$entry.procName
procname
])
let hint = getHint(entry)
if hint.len > 0:
@ -457,9 +486,9 @@ when defined(chronosStackTrace):
newMsg.add($entries)
newMsg.add("Exception message: " & exceptionMsg & "\n")
newMsg.add("Exception type:")
# # For debugging purposes
# newMsg.add("Exception type:")
# for entry in getStackTraceEntries(future.error):
# newMsg.add "\n" & $entry
future.error.msg = newMsg