treeform / puppy

Puppy fetches via HTTP and HTTPS
MIT License
185 stars 27 forks source link

SIGSEGV on Linux with orc enabled #11

Closed oakes closed 3 years ago

oakes commented 3 years ago

Running the tests in this repo with gc:orc enabled leads to a SIGSEGV on Ubuntu 20.04 and nim 1.4.6:

Traceback (most recent call last)
/mnt/c/Users/sekao/Documents/puppy/tests/test.nim(5) test
/mnt/c/Users/sekao/Documents/puppy/src/puppy.nim(196) fetch
/home/sekao/.choosenim/toolchains/nim-1.4.6/lib/pure/strutils.nim(408) fetch
SIGSEGV: Illegal storage access. (Attempt to read from nil?)

I tried both in WSL and in a normal VM and got the same result. I did not get the error when i tried on mac OS and windows 10, though.

guzba commented 3 years ago

I looked into this and I do not know why this fails on linux.

Looking at the --expandArc I don't see where headerData or bodyData would be freed. I have made a simplified version and reported this as I'm not seeing a clear answer to what's going wrong.

--expandArc: fetch2

var
  :tmpD
  :tmpD_1
  headerData
  bodyData
try:
  result = Response()
  let curl = easy_init()
  discard easy_setopt(curl, OPT_URL,
    :tmpD = $req.url
    :tmpD)
  discard easy_setopt(curl, OPT_CUSTOMREQUEST,
    :tmpD_1 = toUpperAscii(req.verb)
    :tmpD_1)
  addDefaultHeaders(req)
  var headerList: Pslist
  block :tmp:
    var header
    var i = 0
    let L = len(req.headers)
    block :tmp_1:
      while i < L:
        var :tmpD_2
        header = req.headers[i]
        headerList = slist_append(headerList,
          :tmpD_2 = `&`(header.key, ": ", header.value)
          :tmpD_2)
        inc(i, 1)
        const
          loc`gensym1 = (filename: "C:\\Users\\Me\\.choosenim\\toolchains\\nim-1.4.8\\lib\\system\\iterators.nim",
            line: 204, column: 10)
          ploc`gensym1 = "C:\\Users\\Me\\.choosenim\\toolchains\\nim-1.4.8\\lib\\system\\iterators.nim(204, 11)"
        bind instantiationInfo
        mixin failedAssertImpl
        {.line: (filename: "C:\\Users\\Me\\.choosenim\\toolchains\\nim-1.4.8\\lib\\system\\iterators.nim",
                 line: 204, column: 10).}:
          if not (len(req.headers) == L):
            failedAssertImpl("C:\\Users\\Me\\.choosenim\\toolchains\\nim-1.4.8\\lib\\system\\iterators.nim(204, 11) `len(a) == L` the length of the seq changed while iterating over it")
        `=destroy`(:tmpD_2)
  discard easy_setopt(curl, OPT_HTTPHEADER, headerList)
  if (
    0 < len(req.body)):
    discard easy_setopt(curl, OPT_POSTFIELDS, req.body)
  headerData = new string
  bodyData = new string
  discard easy_setopt(curl, OPT_FILE, bodyData)
  discard easy_setopt(curl, OPT_WRITEFUNCTION, curlWriteFn)
  discard easy_setopt(curl, OPT_WRITEHEADER, headerData)
  discard easy_setopt(curl, OPT_HEADERFUNCTION, curlWriteFn)
  discard easy_setopt(curl, OPT_CAINFO, "cacert.pem")
  discard easy_setopt(curl, OPT_FOLLOWLOCATION, 1)
  let ret = easy_perform(curl)
  `=copy`(result.url_1, req.url)
  if ret == E_OK:
    var :tmpD_3
    try:
      var httpCode: uint32
      discard easy_getinfo(curl, INFO_RESPONSE_CODE, addr(httpCode))
      result.code = int(httpCode)
      if
        :tmpD_3 = result.headers_1["Content-Encoding"]
        :tmpD_3 ==
          "gzip":
        `=copy_1`(result.body_1, when nimvm:
          vmSeq2Str(uncompress(vmStr2Seq(result.body_1), dfGzip))
        else:
          cast[string](uncompress(cast[seq[uint8]](result.body_1), dfGzip))    
        )
    finally:
      `=destroy`(:tmpD_3)
  else:
    `=sink`(result.error, $easy_strerror(ret))
  easy_cleanup(curl)
  slist_free_all(headerList)
finally:
  `=destroy_1`(bodyData)
  `=destroy_1`(headerData)
  `=destroy`(:tmpD_1)
  `=destroy`(:tmpD)
-- end of expandArc ------------------------
treeform commented 3 years ago

I am pretty sure this got fixed with: https://github.com/treeform/puppy/pull/16

Please reopen issues the issue if you still have trouble.