summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2020-10-19 22:30:37 +0200
committerAleksander Morgado <aleksander@aleksander.es>2020-10-21 12:31:01 +0200
commit6e8f36a619beff8f193701d56ea62645b03a4c0f (patch)
tree7dc780fe11526629b64471b053427bef14b10172
parentc3b09d39d27aa37de55db9252bf4effa4d8657b7 (diff)
broadband-modem-qmi: fix crash when device removed during init
If the modem goes away (ports removed) during the initialization phase (e.g. while QMI clients are being allocated), the MMPortQmi object will be closed and it will lose its internal QmiDevice. We should therefore consider the lack of QmiDevice a valid usecase in track_qmi_device_removed() and return a GError when that happens. #0 0x00007fb544618cc9 in raise () from /lib/libc.so.6 #1 0x00007fb54461bd68 in abort () from /lib/libc.so.6 #2 0x00007fb544e2213d in g_assertion_message () from /usr/lib/libglib-2.0.so.0 #3 0x00007fb544e221ba in g_assertion_message_expr () from /usr/lib/libglib-2.0.so.0 #4 0x00000000004be584 in track_qmi_device_removed () #5 0x00000000004be5e3 in allocate_next_client () #6 0x00000000004be7b1 in qmi_port_allocate_client_ready () #7 0x00007fb5453690a3 in g_task_return_now () from /usr/lib/libgio-2.0.so.0 #8 0x00007fb54536967e in g_task_return () from /usr/lib/libgio-2.0.so.0 #9 0x00000000004dd8f8 in allocate_client_ready () #10 0x00007fb5453690a3 in g_task_return_now () from /usr/lib/libgio-2.0.so.0 #11 0x00007fb54536967e in g_task_return () from /usr/lib/libgio-2.0.so.0 #12 0x00007fb54591d4de in allocate_cid_ready () from /usr/lib/libqmi-glib.so.5 ... (cherry picked from commit 8a54baa346c7fe375b2683e2e333104acf648eff)
-rw-r--r--src/mm-broadband-modem-qmi.c34
1 files changed, 26 insertions, 8 deletions
diff --git a/src/mm-broadband-modem-qmi.c b/src/mm-broadband-modem-qmi.c
index b8a7d1a4..5e99deb1 100644
--- a/src/mm-broadband-modem-qmi.c
+++ b/src/mm-broadband-modem-qmi.c
@@ -9316,20 +9316,26 @@ qmi_device_removed_cb (QmiDevice *device,
mm_base_modem_set_valid (MM_BASE_MODEM (self), FALSE);
}
-static void
-track_qmi_device_removed (MMBroadbandModemQmi *self,
- MMPortQmi *qmi)
+static gboolean
+track_qmi_device_removed (MMBroadbandModemQmi *self,
+ MMPortQmi *qmi,
+ GError **error)
{
QmiDevice *device;
device = mm_port_qmi_peek_device (qmi);
- g_assert (device);
+ if (!device) {
+ g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
+ "Cannot track QMI device removal: QMI port no longer available");
+ return FALSE;
+ }
self->priv->qmi_device_removed_id = g_signal_connect (
device,
QMI_DEVICE_SIGNAL_REMOVED,
G_CALLBACK (qmi_device_removed_cb),
self);
+ return TRUE;
}
static void
@@ -9378,14 +9384,20 @@ static void
allocate_next_client (GTask *task)
{
InitializationStartedContext *ctx;
- MMBroadbandModemQmi *self;
+ MMBroadbandModemQmi *self;
self = g_task_get_source_object (task);
ctx = g_task_get_task_data (task);
if (ctx->service_index == G_N_ELEMENTS (qmi_services)) {
+ GError *error = NULL;
+
/* Done we are, track device removal and launch parent's callback */
- track_qmi_device_removed (self, ctx->qmi);
+ if (!track_qmi_device_removed (self, ctx->qmi, &error)) {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
parent_initialization_started (task);
return;
}
@@ -9454,6 +9466,7 @@ initialization_started (MMBroadbandModem *self,
{
InitializationStartedContext *ctx;
GTask *task;
+ GError *error = NULL;
ctx = g_new0 (InitializationStartedContext, 1);
ctx->qmi = mm_base_modem_get_port_qmi (MM_BASE_MODEM (self));
@@ -9466,7 +9479,7 @@ initialization_started (MMBroadbandModem *self,
g_task_return_new_error (task,
MM_CORE_ERROR,
MM_CORE_ERROR_FAILED,
- "Cannot initialize: QMI port went missing");
+ "Cannot initialize: QMI port no longer available");
g_object_unref (task);
return;
}
@@ -9474,7 +9487,12 @@ initialization_started (MMBroadbandModem *self,
if (mm_port_qmi_is_open (ctx->qmi)) {
/* Nothing to be done, just track device removal and launch parent's
* callback */
- track_qmi_device_removed (MM_BROADBAND_MODEM_QMI (self), ctx->qmi);
+ if (!track_qmi_device_removed (MM_BROADBAND_MODEM_QMI (self), ctx->qmi, &error)) {
+ g_task_return_error (task, error);
+ g_object_unref (task);
+ return;
+ }
+
parent_initialization_started (task);
return;
}