Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to improve run time error tracking ?



  • I like to test my own implementation of "error" signal function.
    For test purpose I have removed all of mine local bluetooth adapters.

    Unfortunately I am receiving this run time error from so far unidentified code, hence I am unable to test my error signal function .

    qt.bluetooth.bluez: Cannot find Bluez 5 adapter for device search true

    Since I do few inquires for local adapters, at various places , I am having difficult time identifying EXACT or approximate location of code generating this run time error.

    Tracking debug output does not help much .

    **Are there any other ways to narrow down the "source" of the run time error ?
    ( In QtCreator / Linux )


  • Lifetime Qt Champion

    @AnneRanch said in How to improve run time error tracking ?:

    emit q->error

    It is not necessary to use "emit" to emit a signal, so these are same:

    emit q->error(...);
    q->error(...);
    

  • Lifetime Qt Champion

    @AnneRanch said in How to improve run time error tracking ?:

    Are there any other ways to narrow down the "source" of the run time error ?

    In Qt source code



  • @jsulm said in How to improve run time error tracking ?:

    @AnneRanch said in How to improve run time error tracking ?:

    Are there any other ways to narrow down the "source" of the run time error ?

    In Qt source code

    I hope you are not joking.

    Can you give me an example of actually accessing the "source code " of Qt class ?
    I like to know how QBluetoothDeviceDiscoveryAgent selects / identifies local / host bluetooth device using QBluetoothLocalDevice class.
    Let;s start with QBluetoothDeviceDiscoveryAgent .





  • @JonB Thanks, how embarrassing.
    I actually have my own clone of qtconnectivity.
    BTW I did identify the code "generating the error " - "start" scan - and it should have been obvious too.
    Now I need to "send" the run time error to to text box so user can see it.

    Edit
    AS always -spoke too soon.
    It looks as the message I am getting is NOT coming from the Qt class , but from "blueZ" - it said so! I will have to go back to one of mine previous posts as make sure I can log messages generated by "blueZ".

    More edit
    No problem , logging category QT_BT is already declared , duh !
    ( how would I get the error in the first place !)
    Q_DECLARE_LOGGING_CATEGORY(QT_BT)

    So - how do I redirect "blueZ" messages category to widget ?
    ( I'll ask Mrs Google )



  • Update
    I have identified the source code of the actual message

    void QBluetoothDeviceDiscoveryAgentPrivate::startBluez5()
    {
    Q_Q(QBluetoothDeviceDiscoveryAgent);

    bool ok = false;
    const QString adapterPath = findAdapterForAddress(m_adapterAddress, &ok);
    if (!ok || adapterPath.isEmpty()) {
        **qCWarning(QT_BT_BLUEZ) << "Cannot find Bluez 5 adapter for device search" << ok;**
        lastError = QBluetoothDeviceDiscoveryAgent::InputOutputError;
        errorString = QBluetoothDeviceDiscoveryAgent::tr("Cannot find valid Bluetooth adapter.");
        q->error(lastError);
        return;
    }
    

    What remains is to "catch" / process the "lasterror" .

    I have noticed that other q->error are coded as
    " emit q->error... "
    Will that stop generating my particular "lasterror" signal?
    If so I may need to find a different way to check for presence of local bluetooth adapters.

    state that
    Q_DECLARE_LOGGING_CATEGORY(QT_BT)

    https://wiki.qt.io/D-Pointer


  • Lifetime Qt Champion

    @AnneRanch said in How to improve run time error tracking ?:

    emit q->error

    It is not necessary to use "emit" to emit a signal, so these are same:

    emit q->error(...);
    q->error(...);
    


  • This post is deleted!


  • Call me stubborn or whatever, I am still not sure how to proceed with this "improvement" without guessing.

    This is my last debugging step / method in QBluetoothDeviceDiscoveryAgent class (straight from doc ) :

    void QBluetoothDeviceDiscoveryAgent::start()
    Starts Bluetooth device discovery, if it is not already started.
    The deviceDiscovered() signal is emitted as each device is discovered. The finished() signal is emitted once device discovery is complete.
    [slot]

    It really does not tell (much) about what comes next - the actual process started , it just states WHAT signals ARE emitted ON SUCCESS . It does not , or cannot , state anything about the timing of these signals or error reporting when the timing is not met.
    Such tracking / control is passed to "library " as far as I can tell, which is OK.
    After some more experimenting , I now know that the Qt "libz" is the one doing the actual "scan for nearby bluetooth devices " .
    Assuming "libz" is Qt configured / derived from "blueZ" and that is about it.

    I am using standard "debugging" process - stepping thru break points is MY source code.

    How can I extend it to "step thru " , at least symbolically , the "libz" - the only connecting / exposed point at this time?
    ( No "libz" binary code does not help.)

    Yes, I can identify SOME source code in "blueZ" ( for example "finished()" signal time-out of 20 seconds ) , but there must be some intermediate layer interfacing Qt class to "libz".
    What is it ?



  • It seems I have been thru this before , if so I apologize.

    This is what "official " github source code looks like ,
    therefore "next step " is
    d->start(supportedDiscoveryMethods());

    void QBluetoothDeviceDiscoveryAgent::start()
    {
    Q_D(QBluetoothDeviceDiscoveryAgent);
    if (!isActive() && d->lastError != InvalidBluetoothAdapterError)
    d->start(supportedDiscoveryMethods());
    }



  • More - this time plain C++ question I need help with

    So the missing link between "libz" is

    d_ptr(new QBluetoothDeviceDiscoveryAgentPrivate(QBluetoothAddress(), this))

    /*!
    Constructs a new Bluetooth device discovery agent with parent \a parent.
    */
    QBluetoothDeviceDiscoveryAgent::QBluetoothDeviceDiscoveryAgent(QObject *parent) :
    QObject(parent),
    d_ptr(new QBluetoothDeviceDiscoveryAgentPrivate(QBluetoothAddress(), this))
    {
    }

    If I am creating the instance of QBluetoothDeviceDiscoveryAgent
    using this constructor , without specifying the adapter nor address

    discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);

    what instructs the build process to use constructor which has the "libray linking " pointer ? It does not look as "default constructor ".
    I know it works - the link to libz - because it correctly identifies missing local bluetooth adapters.


  • Lifetime Qt Champion

    @AnneRanch said in How to improve run time error tracking ?:

    what instructs the build process to use constructor which has the "libray linking " pointer ?

    ??
    Which 'build process', what is a '"libray linking" pointer'?

    I would suggest a c++ book :D


  • Qt Champions 2017

    @AnneRanch said in How to improve run time error tracking ?:

    If I am creating the instance of QBluetoothDeviceDiscoveryAgent
    using this constructor , without specifying the adapter nor address
    discoveryAgent = new QBluetoothDeviceDiscoveryAgent(this);
    what instructs the build process to use constructor which has the "libray linking " pointer ? It does not look as "default constructor ".
    I know it works - the link to libz - because it correctly identifies missing local bluetooth adapters.

    You're confusing a couple of steps that take place.

    Firstly the constructor isn't associated to any linking or libraries directly, it's just a somewhat special class method. It's the compiler that compiles the source code based on the available declarations (it may not have access to all the definitions at the time). It generates a bunch of symbols that it puts in a translation unit (a.k.a. object file). If every definition had been available at the time of compilation all the symbols are going to be resolved at compile time (that is, they're going to have a specific address from the .code section they refer to).

    Secondly, after the compiler'd done its job it comes time for the translation units to be packaged in one binary image (or just binary). which is what the link step is all about. The linker takes all the translation units and matches the symbol references (like method calls, function calls, variable access and such) to their respective addresses. For that to happen the linker has to (and does) build a link-table with the symbols of all object files and matches each unresolved reference from each translation unit to the correct symbol from the correct translation unit. If there are external symbols (that is linked libraries) the linker refers* the references to those external symbols to said libraries.
    * The link process is somewhat different between *nix and windows, where the former resolves the symbol addresses at runtime, while the latter does that at the time of linking.

    Thirdly, when you run your program, that doesn't happen directly. There's a special OS supplied program that does that - the loader. The loader, beside some additional specific work, maps the binary image into memory and does so for all dependent libraries and resolves the relative addressing for PIC (position independent code). On linux it also has the responsibility to resolve the external symbols.

    All that said, a constructor itself does not link anything and is completely oblivious to any external binaries. A constructor is something C++ specific, which has nothing to do with libraries, executables and such.

    PS: libz is the zlib library, which is used for (de)compression and has nothing to do with bluetooth


Log in to reply