Calling sysrand.randomBytes causes Valgrind to mark memory as "possibly lost."
Example
# proof.nim
import nimcrypto/sysrand
var x: int
discard randomBytes(addr(x), sizeof(x))
Compile
$ nim c --gc:arc -d:useMalloc proof.nim
Hint: used config file '/home/user/nim/config/nim.cfg' [Conf]
Hint: used config file '/home/user/nim/config/config.nims' [Conf]
....................
Hint: [Link]
Hint: 41955 lines; 0.729s; 49.098MiB peakmem; Debug build; proj: /home/user/nimcrypto/proof.nim; out: /home/user/nimcrypto/proof [SuccessX]
Run
$ valgrind --error-exitcode=1 --leak-check=yes ./proof
[[Elided output]]
==989== LEAK SUMMARY:
==989== definitely lost: 0 bytes in 0 blocks
==989== indirectly lost: 0 bytes in 0 blocks
==989== possibly lost: 24 bytes in 1 blocks
==989== still reachable: 0 bytes in 0 blocks
==989== suppressed: 0 bytes in 0 blocks
==989==
==989== For counts of detected and suppressed errors, rerun with: -v
==989== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
This "leak" happens because the global RNG is marked as {.threadvar.}:
|
var gSystemRng {.threadvar.}: SystemRng ## System thread global RNG |
but this seems like marking the variable as {.threadvar.} is avoidable entirely. After examining the way gSystemRng is initialized (when being compiled on Linux),
|
proc newSystemRNG(): SystemRng = |
|
result = SystemRng() |
|
|
|
if SYS_getrandom != 0: |
|
var data: int |
|
result.getRandomPresent = true |
|
let res = syscall(SYS_getrandom, addr data, 1, GRND_NONBLOCK) |
|
if res == -1: |
|
let err = osLastError().int32 |
|
if err == ENOSYS or err == EPERM: |
|
result.getRandomPresent = false |
|
|
|
proc getSystemRNG(): SystemRng = |
|
if gSystemRng.isNil: gSystemRng = newSystemRng() |
|
result = gSystemRng |
|
|
it seems that we could have
var gSystemRng: SystemRng = newSystemRNG() ## System thread global RNG
which does not have {.threadvar.}. Are there any issues I am overlooking with this approach?
I agree that this isn't a genuine leak since it is a global variable and the memory always still has a reference, but having Valgrind not complain would be a nice feature to have.
Calling
sysrand.randomBytescauses Valgrind to mark memory as "possibly lost."Example
Compile
Run
This "leak" happens because the global RNG is marked as
{.threadvar.}:nimcrypto/nimcrypto/sysrand.nim
Line 110 in a065c17
but this seems like marking the variable as
{.threadvar.}is avoidable entirely. After examining the waygSystemRngis initialized (when being compiled on Linux),nimcrypto/nimcrypto/sysrand.nim
Lines 112 to 127 in a065c17
it seems that we could have
which does not have
{.threadvar.}. Are there any issues I am overlooking with this approach?I agree that this isn't a genuine leak since it is a global variable and the memory always still has a reference, but having Valgrind not complain would be a nice feature to have.