Page MenuHomePhabricator

Edbg
Updated 2,364 Days AgoPublic

Introduction

This document describes Edbg - a new debugger app that is currently in very early development process.

Purpose

The purpose of Edbg is to be a debugger tool for elementary apps.

It will operate by "live" debugging messages and not by "snapshots" like clouseau. meaning each time specific event will happen - debug messages will be sent.

It will have an option to run function on eo object on the app. for example to set a property in the eo object.

It will have an option to connect to remote device ( like mobile phone ) or to localhost. just like clouseau.

The client will be able to run new app or connect to exiting app.

Requirements

It will support : linux, windows, mac.

Assumptions

The app should be written under elementary.

Debug flag in the system should be turned on.

Communication

ecore_con_eet.

Communication scheme:
{F12914, width=500}
Firstly we need to set the Edbg flag in the system ( elm_conf ) to true. Which will spawn the daemon and will create new threads for each EFL app - dbg thread.
The GUI client will connects only with the daemon. the dbg thread will connect to the daemon and ask him which debug info he wants ( eo add , eo do .. ). Than the thread will increment those values by one and will send just that debug info to the daemon.
when the app will shut down all those value will decrement by one.

Operations Modes

Run from CLI
Run from tool
Debugger attach
...

How will it work?

1)the daemon will spawn new childs using ecore_exe.
2)the daemon will be able to connects to existing apps using ecore_con_eet.
3)on the app side: debug messages will be send to the debug thread that will send them to the daemon.
4)On each wanted EFL file there will be int variables for each wanted debug info ( eo_edbg_eo_do ). In each wanted place we will use Eina_unlikly to check: if this variable > 0 : send dbg info to thread.
5)The app will constantly send data - of new events - to the daemon - and the daemon to the client. which in turn will built a list of objects and their properties. like in clouseau. if the client will get the eo of the objects there will be an option to change the properties.

Profile

We we connects to an app we will send the wanted debug profile.
Eamples:
1)Eo - eo_add eo_do types= evas , evas - all
2)Eo - all , ecore - ecore_thread, Eo

  1. Eo - timers ( update values each max/min 1 min )

Observers

The client can choose object to observe - to send specific debug data on that object.
It can be selected through the app itself - right click on the specified object and selecting observer/observer children.

Highlights

like in Clouseau we can highlight the objects in the gui of the app.
*Maybe to add constant marking on the objects - for example id of the object.

Snapshots

when we first attach to app we have no knowledge on the already existing objects. In that case we will go through all the objects in the system
(by the debug profile) and for each objects : we will go through each of his getters functions.
That way we will gather all the objects properties that we can. We will send it to daemon that will send it to the clients.

Communication data structures

We use ecore_con_eet so all data sctructures will be eet based.
for sending objects values from app to daemon we are building the following DS on the app:
{F12912}
Data is unique per events but mostly a list of values of different types.
Examples:
1)for snapshots = data is a list of the values returned from the getters of the Eo And the Eo id.
2)for eo_do = data is the function name and Eo id. If its a sette - also the changed values.

Disassemble objects values DS

We will use Eolane. By reading the eo file of the objects with eolane we can figured out the types and order of the values that we will get from the getters ( for snapshot event) - the values in the void* data value. by combination with event type that all the information that we need for disassembling.

Wishlist

1)Logging and statistics on memory use:
we can use the following structure to follow macro use in some part or the whole application:

  #include <malloc.h>                                                            
  #include <execinfo.h>

extern void *__libc_malloc(size_t size);                                        
                                                                                   
  int malloc_hook_active = 1;                                                      
  size_t total_malloc=0;                                                          
  void*                                                                            
  my_malloc_hook (size_t size, void *caller)                                      
  {                                                                                
     void *result;                                                                
                                                                                   
     // deactivate hooks for logging                                              
     malloc_hook_active = 0;                                                      
                                                                                   
     result = malloc(size);                                                        
                                                                                   
    //logging                                                                                                          
    // backtrace_symbols_fd(&caller, 1, 1);                                          
     total_malloc+=size;                                                          
     // reactivate hooks                                                          
     malloc_hook_active = 1;                                                      
                                                                                   
     return result;                                                                
  }                                                                                
                                                                                   
  void*                                                                            
  malloc (size_t size)                                                            
  {                                                                                
     void *caller = __builtin_return_address(0);                                  
     if (malloc_hook_active)                                                      
        return my_malloc_hook(size, caller);                                      
     return __libc_malloc(size);                                                  
  }
  1. we can put terminal with gdb inside the client gui .

we will create a function in the application . The gdb will set a breakpoint at that function.
Now we can a put some condition by edbg on the application ( evas object created, obj privateData.id=5 ..). when that condition will become true we will jump to function that we declared and gdb will stop the application.

we can also add buttons to the client that will control gdb (continue, next line .. );

  1. we can use python scripts inside gdb to create new commands and gather useful stats.

for example: number of times we run some function.
reference: tromey.com/blog/?p=501

Last Author
avilog
Last Edited
Feb 9 2015, 8:54 AM
Projects
None
Subscribers
JackDanielZ