Keep on getting a segmentation fault when running ...
# kotlin-native
n
Keep on getting a segmentation fault when running the Kotlin Native program, and wonder if the macro wrapper (in the def file) is correct:
Copy code
# ...
---
static inline MQTTClient_connectOptions createMqttConnectionOptions() {
    MQTTClient_connectOptions options = MQTTClient_connectOptions_initializer;
    return options;
}
Below is the function where the segmentation fault occurs (on the line where the
MQTTClient_connect
function is called):
Copy code
// ...
private fun setupMqttSubscription(settings: Map<String, String>): Unit = memScoped {
    val address = settings["address"] ?: ""
    val clientId = settings["clientId"] ?: ""
    val topic = settings["topic"] ?: ""
    val client = allocArray<MQTTClientVar>(1)
    val connOptions = createMqttConnectionOptions()
    val qos = 1

    MQTTClient_create(client, address, clientId, MQTTCLIENT_PERSISTENCE_NONE, null)
    connOptions.ptr.pointed.keepAliveInterval = 20
    connOptions.ptr.pointed.cleansession = 1
    MQTTClient_setCallbacks(client, null, null, null, staticCFunction(::onMessageReceived))
    println("Connecting to MQTT Broker...")
    val rc = MQTTClient_connect(client, connOptions)
    if (rc != MQTTCLIENT_SUCCESS) {
        println("Failed to connect (error code $rc)")
        exit(-1)
    }
    println("Subscribing to topic $topic for client $clientId using QoS $qos...")
    MQTTClient_subscribe(client, topic, qos)
}
// ...
m
Of course it is incorrect - classical "use after free". Add
static
before
MQTTClient_connectOption
n
The MQTTClientVar type with the read only
client
property is the one I'am not sure about. Here are the relevant definitions in the knm file:
Copy code
public typealias MQTTClient = kotlinx.cinterop.COpaquePointer

public typealias MQTTClientVar = kotlinx.cinterop.CPointerVarOf<paho_mqtt.MQTTClient>
Do wonder if the
MQTTClient_create
function is properly initialising
client
.
Here is the location in the Paho MQTT lib where the seg fault occurs: https://github.com/eclipse/paho.mqtt.c/blob/d631449f16ec78c37e063c220eb6cfc546a4facb/src/MQTTClient.c#L1503 Looks as though the client
property
isn't being properly initialised by the
MQTTClient_create
function.
Here is the truncated output from valgrind:
Copy code
==16462== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==16462== Command: ./mqtt_client.kexe
==16462== 
Starting MQTT Client...
Settings:
* address: <tcp://xxx.xx.xx:xxxx>
* clientId: ExampleClientSub
* topic: MQTT Examples
* timeout: 10000
* qos: 1
Connecting to MQTT Broker...
==16462== Invalid read of size 4
==16462==    at 0x64731AA: MQTTClient_connect (MQTTClient.c:1503)
A bit puzzling when the
client
property's first element contains a pointer after a call to the
MQTTClient_create
function, eg: CPointer(raw=0x545d14)
Discovered what was really causing the segmentation fault. Was passing through a pointer to the array (
MQTTClient_connect(client, connOptions)
) instead of passing through a pointer to the first element in the array (
MQTTClient_connect(client[0], connOptions)
) 🤦‍♂️ .
107 Views