mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-03-03 07:29:23 +00:00
Fix greenbean example
The memory leak detector was crashing. When using gc() you shouldn't use the CheckForMemoryLeaks() function from inside the same function, due to how it runs the atexit handlers.
This commit is contained in:
parent
f590e96abd
commit
3f2a1b696e
4 changed files with 8 additions and 30 deletions
|
@ -289,10 +289,11 @@ int main(int argc, char *argv[]) {
|
|||
// print all the ips that 0.0.0.0 would bind
|
||||
// Cosmo's GetHostIps() API is much easier than ioctl(SIOCGIFCONF)
|
||||
uint32_t *hostips;
|
||||
for (hostips = gc(GetHostIps()), i = 0; hostips[i]; ++i) {
|
||||
for (hostips = GetHostIps(), i = 0; hostips[i]; ++i) {
|
||||
kprintf("listening on http://%hhu.%hhu.%hhu.%hhu:%hu\n", hostips[i] >> 24,
|
||||
hostips[i] >> 16, hostips[i] >> 8, hostips[i], PORT);
|
||||
}
|
||||
free(hostips);
|
||||
|
||||
// secure the server
|
||||
//
|
||||
|
@ -342,7 +343,7 @@ int main(int argc, char *argv[]) {
|
|||
unassert(!pthread_attr_setguardsize(&attr, getpagesize()));
|
||||
unassert(!pthread_attr_setsigmask_np(&attr, &block));
|
||||
unassert(!pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0));
|
||||
pthread_t *th = gc(calloc(threads, sizeof(pthread_t)));
|
||||
pthread_t *th = calloc(threads, sizeof(pthread_t));
|
||||
for (i = 0; i < threads; ++i) {
|
||||
int rc;
|
||||
++a_workers;
|
||||
|
@ -399,6 +400,7 @@ int main(int argc, char *argv[]) {
|
|||
for (i = 0; i < threads; ++i) {
|
||||
unassert(!pthread_join(th[i], 0));
|
||||
}
|
||||
free(th);
|
||||
|
||||
// close the server socket
|
||||
if (!IsWindows())
|
||||
|
|
|
@ -33,28 +33,6 @@ forceinline bool PointerNotOwnedByParentStackFrame(struct StackFrame *frame,
|
|||
((intptr_t)ptr < (intptr_t)parent));
|
||||
}
|
||||
|
||||
static void TeardownGc(void) {
|
||||
struct Garbages *g;
|
||||
struct CosmoTib *t;
|
||||
if (__tls_enabled) {
|
||||
t = __get_tls();
|
||||
if ((g = t->tib_garbages)) {
|
||||
// exit() currently doesn't use gclongjmp() like pthread_exit()
|
||||
// so we need to run the deferred functions manually.
|
||||
while (g->i) {
|
||||
--g->i;
|
||||
((void (*)(intptr_t))g->p[g->i].fn)(g->p[g->i].arg);
|
||||
}
|
||||
free(g->p);
|
||||
free(g);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
__attribute__((__constructor__(51))) static textstartup void InitGc(void) {
|
||||
atexit(TeardownGc);
|
||||
}
|
||||
|
||||
// add item to garbage shadow stack.
|
||||
// then rewrite caller's return address on stack.
|
||||
static void DeferFunction(struct StackFrame *frame, void *fn, void *arg) {
|
||||
|
|
|
@ -68,8 +68,10 @@ static void _pthread_ungarbage(struct CosmoTib *tib) {
|
|||
tib->tib_garbages = 0;
|
||||
while (g->i--)
|
||||
((void (*)(intptr_t))g->p[g->i].fn)(g->p[g->i].arg);
|
||||
_weaken(free)(g->p);
|
||||
_weaken(free)(g);
|
||||
if (_weaken(free)) {
|
||||
_weaken(free)(g->p);
|
||||
_weaken(free)(g);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,6 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/errno.h"
|
||||
#include "libc/thread/thread.h"
|
||||
|
||||
/**
|
||||
|
@ -33,11 +32,8 @@
|
|||
*
|
||||
* @param guardsize contains guard size in bytes
|
||||
* @return 0 on success, or errno on error
|
||||
* @raise EINVAL if `guardsize` is zero
|
||||
*/
|
||||
errno_t pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize) {
|
||||
if (!guardsize)
|
||||
return EINVAL;
|
||||
attr->__guardsize = guardsize;
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue