aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <nhofmeyr@sysmocom.de>2023-03-30 23:51:55 +0200
committerNeels Hofmeyr <nhofmeyr@sysmocom.de>2023-03-31 00:09:13 +0200
commitda4b9e64dcfaf46b979cc9f68afdb273ffbc5cc7 (patch)
treeb569db337efd55ada8518a196efb0c96470c2b80
parent4de07697203804f188f01002bfc5c113d2950ac3 (diff)
attempt to catch a segfault: lchan pointing at stale connneels/os5982
-rw-r--r--src/osmo-bsc/bsc_subscr_conn_fsm.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/src/osmo-bsc/bsc_subscr_conn_fsm.c b/src/osmo-bsc/bsc_subscr_conn_fsm.c
index de9d4d248..31812f2d4 100644
--- a/src/osmo-bsc/bsc_subscr_conn_fsm.c
+++ b/src/osmo-bsc/bsc_subscr_conn_fsm.c
@@ -1094,6 +1094,38 @@ static void gscon_fsm_allstate(struct osmo_fsm_inst *fi, uint32_t event, void *d
}
}
+/* Sanity check / debug shim to catch cleanup failures: iterate all lchans and make sure none are still pointing at this
+ * conn. */
+static void ensure_conn_unused(struct gsm_subscriber_connection *conn)
+{
+ struct gsm_bts *bts;
+ struct gsm_network *network = bsc_gsmnet;
+
+ llist_for_each_entry(bts, &network->bts_list, list) {
+ struct gsm_bts_trx *trx;
+
+ llist_for_each_entry(trx, &bts->trx_list, list) {
+ int i;
+ for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
+ struct gsm_bts_trx_ts *ts = &trx->ts[i];
+ struct gsm_lchan *lchan;
+
+ ts_for_n_lchans(lchan, ts, ts->max_lchans_possible) {
+ if (lchan->conn == conn) {
+ LOG_LCHAN(lchan, LOGL_ERROR,
+ "This lchan still points at discarded conn %s\n",
+ osmo_fsm_inst_name(conn->fi));
+ LOGPFSML(conn->fi, LOGL_ERROR,
+ "This conn is discarding, but lchan is still pointing at this conn: %s\n",
+ lchan->name);
+ lchan->conn = NULL;
+ }
+ }
+ }
+ }
+ }
+}
+
static void gscon_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
{
struct gsm_subscriber_connection *conn = fi->priv;
@@ -1123,6 +1155,8 @@ static void gscon_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cau
conn->bsub = NULL;
}
+ ensure_conn_unused(conn);
+
llist_del(&conn->entry);
talloc_free(conn);
}