Fix a refcount bug.

This commit is contained in:
C. Guy Yarvin 2014-10-06 10:17:33 -07:00
parent 27c67acca4
commit 3c6398c106
9 changed files with 120 additions and 84 deletions

19
g/a.c
View File

@ -900,6 +900,25 @@ u3_ca_use(u3_noun som)
} }
} }
/* u3_ca_audit(): investigate object.
*/
c3_o
u3_ca_audit(u3_noun som)
{
if ( u3_so(u3_co_is_cat(som)) ) {
return u3_yes;
}
if ( 0 == u3_ca_use(som) ) {
u3_cm_p("som", som);
printf("zero: %x/%x\r\n", u3_cr_mug(som), som);
return u3_no;
}
else if ( u3_so(u3du(som)) ) {
return u3_and(u3_ca_audit(u3h(som)), u3_ca_audit(u3t(som)));
}
else return u3_yes;
}
/* u3_ca_slab(): create a length-bounded proto-atom. /* u3_ca_slab(): create a length-bounded proto-atom.
*/ */
c3_w* c3_w*

18
g/j.c
View File

@ -82,11 +82,10 @@ u3_cj_find(u3_noun bat)
{ {
u3_cs_road* rod_u = u3R; u3_cs_road* rod_u = u3R;
while ( rod_u->par_u ) { while ( rod_u->par_u && u3_so(u3_co_is_senior(rod_u, bat)) ) {
if ( u3_so(u3_co_is_senior(rod_u, bat)) ) { rod_u = rod_u->par_u;
rod_u = rod_u->par_u;
}
} }
{ {
u3_weak jax = u3_ch_get(rod_u->jed.har_u, bat); u3_weak jax = u3_ch_get(rod_u->jed.har_u, bat);
@ -519,10 +518,8 @@ _cj_save(u3_noun bat,
u3_cs_road* rod_u = u3R; u3_cs_road* rod_u = u3R;
u3_cs_road* tmp_u; u3_cs_road* tmp_u;
while ( rod_u->par_u ) { while ( rod_u->par_u && u3_so(u3_co_is_senior(rod_u, bat)) ) {
if ( u3_so(u3_co_is_senior(rod_u, bat)) ) { rod_u = rod_u->par_u;
rod_u = rod_u->par_u;
}
} }
tmp_u = u3R; tmp_u = u3R;
@ -644,9 +641,10 @@ u3_cj_mine(u3_noun clu,
u3D.ray_u[jax_l].par_u = par_u; u3D.ray_u[jax_l].par_u = par_u;
c3_assert(0 != jax_l); c3_assert(0 != jax_l);
free(nam_c); free(nam_c);
#if 0
fprintf(stderr, "mine: bound jet %d/%s\r\n", fprintf(stderr, "mine: bound jet %d/%s\r\n",
cop_u->jax_l, cop_u->cos_c); cop_u->jax_l, cop_u->cos_c);
#endif
break; break;
} }
i_l++; i_l++;
@ -662,7 +660,7 @@ u3_cj_mine(u3_noun clu,
fak_u.axe_l = axe_l; fak_u.axe_l = axe_l;
jax_l = _cj_insert(&fak_u); jax_l = _cj_insert(&fak_u);
fprintf(stderr, "mine: dummy jet %d/%s\r\n", jax_l, fak_u.cos_c); // fprintf(stderr, "mine: dummy jet %d/%s\r\n", jax_l, fak_u.cos_c);
} }
u3z(clu); u3z(clu);

135
g/m.c
View File

@ -10,8 +10,7 @@
#include "all.h" #include "all.h"
static jmp_buf Signal_u; static jmp_buf u3_Signal;
static c3_l Signal_l;
#ifndef SIGSTKSZ #ifndef SIGSTKSZ
# define SIGSTKSZ 16384 # define SIGSTKSZ 16384
@ -24,7 +23,7 @@ void u3_unix_ef_move(void); // restore system signal regime
extern void extern void
u3_lo_sway(c3_l tab_l, u3_noun tax); u3_lo_sway(c3_l tab_l, u3_noun tax);
#if 1 #if 0
/* _cm_punt(): crudely print trace. /* _cm_punt(): crudely print trace.
*/ */
static void static void
@ -53,19 +52,12 @@ _cm_emergency(c3_c* cap_c, c3_l sig_l)
write(2, "\r\n", 2); write(2, "\r\n", 2);
} }
static void _cm_overflow_over(void *arg1, void *arg2, void *arg3) static void _cm_overflow(void *arg1, void *arg2, void *arg3)
{ {
(void)(arg1); (void)(arg1);
(void)(arg2); (void)(arg2);
(void)(arg3); (void)(arg3);
siglongjmp(Signal_u, c3__over); siglongjmp(u3_Signal, c3__over);
}
static void _cm_overflow_dire(void *arg1, void *arg2, void *arg3)
{
(void)(arg1);
(void)(arg2);
(void)(arg3);
siglongjmp(Signal_u, c3__dire);
} }
/* _cm_signal_handle(): handle a signal in general. /* _cm_signal_handle(): handle a signal in general.
@ -73,33 +65,11 @@ static void _cm_overflow_dire(void *arg1, void *arg2, void *arg3)
static void static void
_cm_signal_handle(c3_l sig_l) _cm_signal_handle(c3_l sig_l)
{ {
c3_l org_l = sig_l; if ( c3__over == sig_l ) {
sigsegv_leave_handler(_cm_overflow, NULL, NULL, NULL);
_cm_emergency("signal", sig_l);
if ( Signal_l || (u3R == &u3H->rod_u) ) {
_cm_emergency("signal overlap: old", Signal_l);
_cm_emergency("signal overlap: new", sig_l);
if ( c3__prof == sig_l ) {
// Ignore strange profiling event.
//
return;
}
sig_l = c3__dire;
}
Signal_l = sig_l;
if ( c3__over == org_l ) {
if ( c3__dire == sig_l ) {
sigsegv_leave_handler(_cm_overflow_dire, NULL, NULL, NULL);
}
else {
sigsegv_leave_handler(_cm_overflow_over, NULL, NULL, NULL);
}
} }
else { else {
siglongjmp(Signal_u, sig_l); siglongjmp(u3_Signal, sig_l);
} }
} }
@ -118,6 +88,7 @@ _cm_signal_handle_term(int x)
static void static void
_cm_signal_handle_intr(int x) _cm_signal_handle_intr(int x)
{ {
abort();
_cm_signal_handle(c3__intr); _cm_signal_handle(c3__intr);
} }
@ -140,21 +111,45 @@ _cm_signal_reset(void)
/* _cm_signal_recover(): recover from a deep signal, after longjmp. /* _cm_signal_recover(): recover from a deep signal, after longjmp.
*/ */
static u3_noun static u3_noun
_cm_signal_recover(void) _cm_signal_recover(c3_l sig_l)
{ {
_cm_emergency("recover", Signal_l); u3_noun tax;
if ( c3__dire == Signal_l ) { // XX: special handling for profile signal.
Signal_l = 0; //
// Unlikely to be set, but it can be made to happen.
//
tax = u3R->bug.tax;
u3R->bug.tax = 0;
if ( &(u3H->rod_u) == u3R ) {
// A top-level crash - rather odd. We should GC here.
//
_cm_emergency("recover: top", sig_l);
// Reset the top road - the problem could be a fat cap.
//
_cm_signal_reset(); _cm_signal_reset();
return u3nt(3, c3__dire, 0);
if ( (c3__meme == sig_l) && (u3_co_open(u3R) <= 256) ) {
// Out of memory at the top level. Error becomes c3__full,
// and we release the emergency buffer. To continue work,
// we need to readjust the image, eg, migrate to 64 bit.
//
u3z(u3R->bug.mer);
sig_l = c3__full;
}
return u3nt(3, sig_l, tax);
} }
else { else {
u3_noun tax = u3_nul;
u3_noun pro; u3_noun pro;
// Descend to the road that caused the problem - in almost all // A signal was generated while we were within Nock.
// cases the innermost road, except for a //
_cm_emergency("recover: dig", sig_l);
// Descend to the innermost trace, collecting stack.
// //
{ {
u3_cs_road* rod_u; u3_cs_road* rod_u;
@ -167,13 +162,12 @@ _cm_signal_recover(void)
rod_u = rod_u->kid_u; rod_u = rod_u->kid_u;
} }
} }
u3_lo_sway(2, u3k(tax)); // XX
abort(); // XX
pro = u3nt(3, sig_l, tax);
_cm_signal_reset(); _cm_signal_reset();
pro = u3nt(3, Signal_l, tax);
_cm_punt(tax);
u3_lo_sway(2, u3k(tax));
Signal_l = 0;
return pro; return pro;
} }
} }
@ -222,6 +216,14 @@ _cm_signal_done()
u3_unix_ef_move(); u3_unix_ef_move();
} }
/* u3_cm_signal(): treat a nock-level exception as a signal interrupt.
*/
void
u3_cm_signal(u3_noun sig_l)
{
siglongjmp(u3_Signal, sig_l);
}
/* u3_cm_file(): load file, as atom, or bail. /* u3_cm_file(): load file, as atom, or bail.
*/ */
u3_noun u3_noun
@ -323,6 +325,7 @@ _boot_parts(void)
{ {
u3R->cax.har_u = u3_ch_new(); u3R->cax.har_u = u3_ch_new();
u3R->jed.har_u = u3_ch_new(); u3R->jed.har_u = u3_ch_new();
u3R->bug.mer = u3_ci_tape("emergency buffer");
} }
/* u3_cm_boot(): instantiate or activate image. /* u3_cm_boot(): instantiate or activate image.
@ -417,7 +420,7 @@ u3_cm_bail(u3_noun how)
{ {
/* Printf some metadata. /* Printf some metadata.
*/ */
{ if ( c3__exit != how ) {
if ( u3_so(u3ud(how)) ) { if ( u3_so(u3ud(how)) ) {
c3_c str_c[5]; c3_c str_c[5];
@ -432,12 +435,26 @@ u3_cm_bail(u3_noun how)
c3_assert(u3_so(u3ud(u3h(how)))); c3_assert(u3_so(u3ud(u3h(how))));
fprintf(stderr, "bail: %d (at %llu)\r\n", u3h(how), u3N); fprintf(stderr, "bail: %d (at %llu)\r\n", u3h(how), u3N);
u3_cm_p("bail", u3t(how)); // u3_cm_p("bail", u3t(how));
} }
} }
// _cm_punt(); // _cm_punt();
// u3_lo_sway(2, u3k(u3R->bug.tax)); // u3_cm_signal(c3__exit);
abort();
if ( c3__exit != how ) {
u3_lo_sway(2, u3k(u3R->bug.tax));
abort();
}
if ( &(u3H->rod_u) == u3R ) {
// For top-level errors, which shouln't happen often, we have no
// choice but to use the signal process; and we require the flat
// form of how.
//
c3_assert(u3_so(u3_co_is_cat(how)));
u3_cm_signal(how);
}
/* Reconstruct a correct error ball. /* Reconstruct a correct error ball.
*/ */
@ -630,17 +647,20 @@ u3_cm_soft_top(c3_w sec_w, // timer seconds
{ {
u3_noun why, pro; u3_noun why, pro;
c3_w gof_w; c3_w gof_w;
c3_l sig_l;
/* Enter internal signal regime. /* Enter internal signal regime.
*/ */
_cm_signal_deep(0); _cm_signal_deep(0);
if ( 0 != sigsetjmp(Signal_u, 1) ) { if ( 0 != (sig_l = sigsetjmp(u3_Signal, 1)) ) {
// return to blank state // return to blank state
// //
_cm_signal_done(); _cm_signal_done();
return _cm_signal_recover(); // recover memory state from the top down
//
return _cm_signal_recover(sig_l);
} }
/* Record the cap, and leap. /* Record the cap, and leap.
@ -701,9 +721,6 @@ u3_cm_soft_run(u3_noun fly,
u3_noun why, pro; u3_noun why, pro;
c3_w gof_w; c3_w gof_w;
u3_cm_wash(aga);
u3_cm_wash(agb);
/* Record the cap, and leap. /* Record the cap, and leap.
*/ */
{ {

1
g/n.c
View File

@ -379,6 +379,7 @@ u3_noun
u3_cn_nock_an(u3_noun bus, u3_noun fol) u3_cn_nock_an(u3_noun bus, u3_noun fol)
{ {
u3_noun fly = u3nt(u3nc(1, 0), 0, 0); // |=(a=* ~) u3_noun fly = u3nt(u3nc(1, 0), 0, 0); // |=(a=* ~)
u3_noun pro;
return u3_cn_nock_in(fly, bus, fol); return u3_cn_nock_in(fly, bus, fol);
} }

View File

@ -45,6 +45,11 @@
u3_noun u3_noun
u3_ca_take(u3_noun som); u3_ca_take(u3_noun som);
/* u3_ca_audit(): investigate object for bad refcounts.
*/
c3_o
u3_ca_audit(u3_noun som);
/* u3_ca_lose(): lose a reference. /* u3_ca_lose(): lose a reference.
*/ */
void void

View File

@ -18,6 +18,11 @@
# define u3_cm_trap() (u3_noun)(setjmp(u3R->esc.buf)) # define u3_cm_trap() (u3_noun)(setjmp(u3R->esc.buf))
#endif #endif
/* u3_cm_signal(): treat a nock-level exception as a signal interrupt.
*/
void
u3_cm_signal(u3_noun sig_l);
/* u3_cm_bail(): bail out. Does not return. /* u3_cm_bail(): bail out. Does not return.
** **
** Bail motes: ** Bail motes:

View File

@ -144,12 +144,6 @@
c3_w fre_w; // number of free words c3_w fre_w; // number of free words
} all; } all;
struct { // pseudo-interrupt
c3_l zap_l; // double signal, very bad
c3_l sig_l; // interrupt; written by signal
c3_l cry_l; // critical region, or 0
} coy;
struct { // jet dashboard struct { // jet dashboard
u3_ch_root* har_u; // jet index u3_ch_root* har_u; // jet index
} jed; } jed;
@ -160,6 +154,7 @@
struct { // trace stack struct { // trace stack
u3_noun tax; // (list ,*) u3_noun tax; // (list ,*)
u3_noun mer; // emergency buffer to release
} bug; } bug;
struct { // profile stack struct { // profile stack

View File

@ -33,6 +33,7 @@
u3_noun fin = u3t(hoq); u3_noun fin = u3t(hoq);
if ( u3_nul == fin ) { if ( u3_nul == fin ) {
u3_cm_p("cog", cog);
return u3_cm_error("find-none"); return u3_cm_error("find-none");
} }
else { else {

View File

@ -332,8 +332,7 @@ int FOO;
# define _mint_used() # define _mint_used()
static u3_noun static u3_noun
_mint_in( _mint_in(u3_noun van,
u3_noun van,
u3_noun sut, u3_noun sut,
u3_noun gol, u3_noun gol,
u3_noun gen) u3_noun gen)
@ -388,8 +387,7 @@ int FOO;
if ( u3_yes == u3_cr_sing(rex, gen) ) { if ( u3_yes == u3_cr_sing(rex, gen) ) {
#if 1 #if 1
u3_noun zix = u3_cqfu_shep u3_noun zix = u3_cqfu_shep(van, "gene", 'q', u3k(gen));
(van, "gene", 'q', u3k(gen));
u3_ct_push(u3nc(c3__mean, zix)); u3_ct_push(u3nc(c3__mean, zix));
return u3_cm_error("mint-open"); return u3_cm_error("mint-open");
@ -422,7 +420,7 @@ int FOO;
_mint_used(); _mint_used();
{ {
u3_noun nob = u3_cqfl_bunt(van, p_gen); u3_noun nob = u3_cqfl_bunt(van, p_gen);
u3_noun dok = u3nc(c3__cnzz, q_gen); u3_noun dok = u3nc(c3__cnzz, u3k(q_gen));
u3_noun vol = _mint_corn(van, sut, dok); u3_noun vol = _mint_corn(van, sut, dok);
u3_noun axe = _mint_coke(vol); u3_noun axe = _mint_coke(vol);
u3_noun wam = u3_cqfu_play(van, sut, nob); u3_noun wam = u3_cqfu_play(van, sut, nob);
@ -849,10 +847,7 @@ int FOO;
u3_noun hum = _mint_in(van, sut, gol, q_gen); u3_noun hum = _mint_in(van, sut, gol, q_gen);
u3_noun bez = u3nt(c3__spot, 1, u3k(p_gen)); u3_noun bez = u3nt(c3__spot, 1, u3k(p_gen));
ret = u3nc( ret = u3nc(u3k(u3h(hum)), u3nt(10, bez, u3k(u3t(hum))));
u3k(u3h(hum)),
u3nt(10, bez, u3k(u3t(hum))));
u3z(hum); u3z(hum);
} }
u3_ct_drop(); u3_ct_drop();