TE
TechEcho
Home24h TopNewestBestAskShowJobs
GitHubTwitter
Home

TechEcho

A tech news platform built with Next.js, providing global tech news and discussions.

GitHubTwitter

Home

HomeNewestBestAskShowJobs

Resources

HackerNews APIOriginal HackerNewsNext.js

© 2025 TechEcho. All rights reserved.

rand() may call malloc()

212 pointsby adunkabout 3 years ago

25 comments

marcan_42about 3 years ago
The solution isn&#x27;t to stop using rand(). The solution is to stop using newlib.<p>If you&#x27;re doing your own custom memory management like this, you shouldn&#x27;t even <i>have</i> a malloc implementation at all. Even newlib is too bloated for your use case. At this point, chances are you&#x27;re using a trivial subset of the C library and it&#x27;d be easy to roll your own. You can import bits and pieces from other projects (I personally sometimes copy and paste bits from PDClib for this). In such a tight embedded project, chances are you don&#x27;t even have threads; why even pull in that reentrancy code?<p>Freestanding C code with no standard library isn&#x27;t scary. If you need an example, look at what we do for m1n1:<p><a href="https:&#x2F;&#x2F;github.com&#x2F;AsahiLinux&#x2F;m1n1&#x2F;tree&#x2F;main&#x2F;src" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;AsahiLinux&#x2F;m1n1&#x2F;tree&#x2F;main&#x2F;src</a><p>In particular, this is the libc subset we use (we do have malloc here, which is dlmalloc, but still not enough of libc to be worth depending on a full one):<p><a href="https:&#x2F;&#x2F;github.com&#x2F;AsahiLinux&#x2F;m1n1&#x2F;tree&#x2F;main&#x2F;sysinc" rel="nofollow">https:&#x2F;&#x2F;github.com&#x2F;AsahiLinux&#x2F;m1n1&#x2F;tree&#x2F;main&#x2F;sysinc</a>
评论 #30965213 未加载
评论 #30964887 未加载
评论 #30968829 未加载
评论 #30964834 未加载
chrsigabout 3 years ago
So...it wasn&#x27;t really rand() at fault here, it was some reentrancy library that newlib uses...<p>For some reason the blog lists the source for rand_r, to which the caller supplies the state rather than using global state.<p>I wonder if they&#x27;ll run into this with any of the non-reentrant C functions (strtok, I&#x27;m looking at you). It makes their conclusion of &quot;we stopped using rand()&quot; a bit wanting.<p>I mean, it&#x27;s great that they stopped using rand(), that&#x27;s a good move, and pragmatic given their issue, it just feels like it&#x27;s a really surface level conclusion.
评论 #30964596 未加载
评论 #30967459 未加载
AdamH12113about 3 years ago
This sort of thing is why I prefer to leave the C standard library out of my microcontroller code altogether. It keeps me from having to worry about what PC-centric assumptions they may be making under the hood, and they&#x27;re often a bit bloated anyway.<p>Something you do have to watch out for regardless is accidental promotions of floats to doubles. C loves float promotion, and if you&#x27;re not careful (and don&#x27;t use the special compiler options) it&#x27;s easy to turn a one-cycle FPU operation into a hundred-cycle CPU function call.<p>I keep thinking there ought to be a better language for bare-metal microcontroller programming, but the demand for it is so small I&#x27;m not sure who would bother supporting it.
评论 #30964798 未加载
评论 #30964783 未加载
评论 #30966987 未加载
评论 #30964644 未加载
zgsabout 3 years ago
Remove malloc from your libc and catch this entire family of problems at link time.
评论 #30965198 未加载
评论 #30965510 未加载
评论 #30969155 未加载
furyofantaresabout 3 years ago
The article contains a fair bit of fluff that may be aimed at developers without familiarity with embedded systems or I guess C, I&#x27;m not exactly sure what&#x27;s with the tone but the short of it is:<p>- They&#x27;ve got an embedded system with all static allocation (they do mention having a dynamic allocator though)<p>- They&#x27;ve recently found a stack corruption crash which was traced back to rand() calling malloc() which is both unexpected and also malloc should never be called in the system at all<p>- They traced it back to their usage of newlibc configured to add reentant suppose for c functions that don&#x27;t don&#x27;t support it, and this support uses malloc, so when they call rand() this results in a call to malloc()<p>- A recent tooling update caused them to be using newlibc built this way; they previously were using newlibc configured without this feature<p>- Their solution is to not use rand() and instead use a different prng, and to write a tool that detects use of malloc() and fails the build
Animatsabout 3 years ago
This is why Rust has both &quot;std&quot; and &quot;core&quot;. &quot;core&quot; lacks allocation capability.
ajucabout 3 years ago
We had a team project at university to write some graphic demo in 3d from scratch (no open gl, no fancy graphic libraries, just plotting pixels onto screen).<p>We did, and it was pretty slow despite all the microoptimizations (for example we used fixed point math). It was at the time when hyperthreaded CPUs were introduced and my friend added support for multithreading - 1 thread would draw 1 half of the screen. It broke our code and we found out rand() wasn&#x27;t thread-safe.<p>So being the inexperienced dumbasses we were - we added locks around the rand() calls :). Which made the whole multithreading useless but we didn&#x27;t realize it then :) What we should do is implement rand() on local variables, it&#x27;s like 3 lines of code :)
评论 #30966011 未加载
urbandw311erabout 3 years ago
It’s possible the architect of the article is actually a marketeer who wanted to publicise the company and its “careful approach” to IOT. Be careful what you wish for! Now your engineers just look a little inexperienced as a result.
评论 #30966781 未加载
评论 #30966087 未加载
togaenabout 3 years ago
Interesting article, but, man, incredibly annoying writing style. It reads like a LinkedIn post. Use normal sentence&#x2F;paragraph structure and say what you’re going to say.
评论 #30968596 未加载
matthews2about 3 years ago
<p><pre><code> &gt; The stack memory is somewhat tricky to allocate, because its maximum size is determined at runtime. &gt; &gt; There is no silver bullet: we can’t predict it. So we need to measure it. </code></pre> When you&#x27;re extremely memory constrained, you should probably know the max stack depth at different points in your program.<p>GCC has -Wstack-usage=BYTES to warn you if a single function uses more than BYTES of stack space (VLAs and alloca not included), which admittedly isn&#x27;t too useful if your function calls another...
评论 #30966816 未加载
touisteurabout 3 years ago
I know it&#x27;s offtopic, but adding perf probes to glibc&#x27;s malloc in a running system was quite revealing: - qsort calls malloc - and qsort is used a lot in glibc internal functions such as gethostbybame so... Yeah. - snprintf can call malloc too<p>I&#x27;m sure I&#x27;m not finished discovering fun stuff.
nooberminabout 3 years ago
As someone who dabbles with NES programming, 10KB is quite a lot of ram for me. NES programming is almost always in 6502 asm and at least when I do it I don&#x27;t even need the stack. Generally people do not use it for storage, they use the stack just for function calling, and generally uses just a fraction of the zero page for the most part. Instead, every subroutine either gets its own variables somewhere in memory or you use zero page and have to be careful that the interrupt handlers do not disrupt the parts of zero page that other routines might use. It&#x27;s a lot harder perhaps but it does force you to be more intentional with your memory usage. I&#x27;ll admit I&#x27;ve never coded any like crazy demos (yet) but programming in this way, I&#x27;ve yet to use anywhere near to the full 2KB for standard ram the NES has.<p>CHR RAM (like graphics ram, sort of) is a different story perhaps, but at least for the game logic and some sprite manipulation, yeah 2KB for an 8bit game is plenty. I think programming in C (which requires a stack, also probably requires floats which the 6502 has no native support for and would require implementation by the compiler) adds a lot of convenience but the overhead is too much for a NES, although there are libraries and tools for NES C programming out there.
jffhnabout 3 years ago
And in Java, Math.cos(double) might do allocation as well, for large angles reduction. In Jafama I took care to avoid that, by encoding the quadrant in two useless bits of reduced angle exponent.
bombcarabout 3 years ago
Just use dilbert_rand(). Threadsafe reentrant and doesn’t allocate.
SourcePartsabout 3 years ago
Can you.<p>Stop.<p>Writing blog posts.<p>Like Linkedin posts.<p>Like this.<p>It makes them.<p>Hard to read.
评论 #30966605 未加载
SeanLukeabout 3 years ago
His solution is to use a PCG generator? As far as I know its designer withdrew submission of a journal article after negative reviews and has never resubmitted one. And this doesn&#x27;t look good:<p><a href="https:&#x2F;&#x2F;pcg.di.unimi.it&#x2F;pcg.php" rel="nofollow">https:&#x2F;&#x2F;pcg.di.unimi.it&#x2F;pcg.php</a>
评论 #30965139 未加载
评论 #30964832 未加载
评论 #30965239 未加载
评论 #30964835 未加载
languageserverabout 3 years ago
<p><pre><code> int rand_r (unsigned int *seed) { long k; long s = (long)(*seed); if (s == 0) s = 0x12345987; k = s &#x2F; 127773; s = 16807 * (s - k * 127773) - 2836 * k; if (s &lt; 0) s += 2147483647; (*seed) = (unsigned int)s; return (int)(s &amp; RAND_MAX); } </code></pre> Who on this green Earth wrote this??<p><pre><code> long s = (long)(*seed);</code></pre>
评论 #30967474 未加载
jesprenjabout 3 years ago
If malloc() damages the running system, why even implement it in the standard library?
pifabout 3 years ago
If you are developing against a supposed implementation, rather than the published interface, you are wrong. rand is not the culprit, newlib is not the culprit: you are.<p>You don&#x27;t want to use malloc? Don&#x27;t have malloc.
h2odragonabout 3 years ago
Wonder what other joyous opportunities for unforeseen functionality they&#x27;re unknowingly baking into their &quot;IoT&quot; devices.
aaaaaaaaaaababout 3 years ago
I don’t get it. Why does newlib malloc in rand() instead of just storing the global state in a static variable?
评论 #30967624 未加载
评论 #30967151 未加载
ufoabout 3 years ago
Does anyone know why the reentrancy layer needed malloc in the first place? I didn&#x27;t understand that part.
评论 #30966387 未加载
gojomoabout 3 years ago
Is this thus a `malloc()` without a matching `free()`?
评论 #30966385 未加载
naoqjabout 3 years ago
Jesus how annoyingly written.
评论 #30967396 未加载
tedunangstabout 3 years ago
Maybe in an low quality implementation. rand() is not defined to have error conditions, and definitely not assert when malloc fails.