Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [tcf-dev] Problem planting breakpoints

> Hi Stefan,

Hi :)

>>> That's it. You don't need to call iterate_breakpoints(), you should not map breakpoints to their actual memory addresses
>>
>> Well, the problem is that the Agent is not able to do this for me. The compiler I am using is SDCC and I am working with a parser to extract all debug information from the CDB (debug information file) files.

>Did you look at the linenumbers implementation to add a new instance for 
the CDB format? That way the TCF Agent would handle the file:line to 
address translation.

Well, yes I have a new implementation linenumbers_mcs51.c (see attachment; but it's all a little hacky at the moment ^^) which implements line_to_address() and address_to_line(). They are working for me so far as they should. 


> In this case it seems like that I have to ask: What needs to be done so that the Agent tries to plant the breakpoints BEFORE I run the program on my dude (device under debug)?
>The TCF Agent tries to replant breakpoints every time a change is made 
to the context. More precisely it tries to replant the breakpoints when:
- a context is created.
- a context is changed.
- a context exits.
- the path mapping changed.
- the memory maps changed.

Please take a look at debug_event_handler.c which contains my version of that function.

As you can see I catch an event PROGRAMMING_SUCCEEDED which creates two contexts and calls send_context_event_created_event() and also for trial send_context_changed_event(). But if I don't call iterate_breakpoints() I am not able to collect the breakpoints and RunUntilBreakpointHit() gets executed with an empty array.

On the other hand IF I execute iterate_breakpoints() the first breakpoint hit works, but as I hit resume the agent first tries to plant the breakpoints but unfortunately unplants them right after planting which empties my breakpoint list again.. 

I really have no idea why this is the case and which event causes this behaviour ..

Best regards.

Stefan

> Please Note that my agent does not communicate with the device directly instead talks to another server that is already capable of doing so.
>
>
>
> Thank you and best regards,
> Stefan Falk
>
>
> -----Original Message-----
> From: tcf-dev-bounces@xxxxxxxxxxx [mailto:tcf-dev-bounces@xxxxxxxxxxx] On Behalf Of Stefan.Falk@xxxxxxxxxxxx
> Sent: Friday, May 16, 2014 8:47 AM
> To: tcf-dev@xxxxxxxxxxx
> Subject: [tcf-dev] Problem planting breakpoints
>
> Hi and sorry for my third E-Mail today but I seem to have a major issue with the way how breakpoints are set and removed.
>
> Like I said a few times already, all I got is a function CLIDevice_RunUntil(int[] breakpoint_address) to set breakpoints and run my device under debug.
>
> Therefore I call iterate_breakpoints() to collect all file locations and map them to their actual memory addresses.
>
> My problem is still that after the program reaches a  breakpoint, the TCF Agent begins to "plant" breakpoints. The problem isn't that by doing so cpu_bp_plant() gets called and therefore CLIDevice_PlantBreakpoint() gets called, the problem is that immediately after that cpu_bp_remove() is getting called.
>
> I have no idea why this is happening. All I can tell so far is that InstructionRef ref->cnt in validate_bi_refs is zero for some reason the "dirty" flag of BreakInstruction is TRUE gets set there. Therefore it gets deleted later on.
>
> I'm really really stuck here. I've tried the whole day to find out what is wrong but I really don't understand the underlying reason why the agent wants to remove my breakpoints ..
>
> Thanks for your help.
>
> --
> Stefan Falk
>
> Infineon Technologies Austria AG
> Trainee
> Automotive Sense and Control
> Component Verification
>
> Tel:  +43 (0)5 / 1777 - 5439
> Email: stefan.falk@xxxxxxxxxxxx<mailto:stefan.falk@xxxxxxxxxxxx>
>
> "Aim above the mark to hit the mark." - Ralph Waldo Emerson
>
>
>
> _______________________________________________
> tcf-dev mailing list
> tcf-dev@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/tcf-dev
>
>
> This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
>
> _______________________________________________
> tcf-dev mailing list
> tcf-dev@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/tcf-dev
> _______________________________________________
> tcf-dev mailing list
> tcf-dev@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/tcf-dev
>
_______________________________________________
tcf-dev mailing list
tcf-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/tcf-dev
/*******************************************************************************
 * Copyright (c) 2014, Stefan Falk 
 * All rights reserved.
 * 
 * Contributors:
 *     Stefan Falk
 *******************************************************************************/

/*
 * TCF service line Numbers
 * The service associates locations in the source files with the corresponding
 * machine instruction addresses in the executable object.
 */

#include <tcf/config.h>

#if SERVICE_LineNumbers && !ENABLE_LineNumbersProxy && ENABLE_PE

#include <errno.h>
#include <assert.h>
#include <stdio.h>
#include <tcf/framework/json.h>
#include <tcf/framework/protocol.h>
#include <tcf/framework/context.h>
#include <tcf/framework/exceptions.h>
#include <tcf/framework/cache.h>
#include <tcf/services/pathmap.h>
#include <tcf/services/linenumbers.h>
#include <system/Windows/tcf/context-win32.h>
#if ENABLE_LineNumbersMux
#define LINENUMBERS_READER_PREFIX win32_reader_
#include <tcf/services/linenumbers_mux.h>
#endif

#include <ParserInterface.cli.h>

int line_to_address(Context * ctx, char * file, int line, int column,
                    LineNumbersCallBack * callback, void * user_args) {
    int err = 0;
    int address = 0;

    if(err == 0) {
        CodeArea area;

        memset(&area, 0, sizeof(area));

        address = CLIParser_GetAddressFromLineInFile(file, line);

        if(address == -1)
            return -1;
        
        area.file = file;
        area.start_line = line;
        area.start_address = address;
        area.end_line = line;
        area.end_address = address;
        callback(&area, user_args);
    }
	
    return 0;
}

int address_to_line(Context * ctx, ContextAddress addr0, ContextAddress addr1, LineNumbersCallBack * callback, void * user_args) {
    
    int err = 0;
    int not_found = 0;
    int line = -1;
    char *file = 0;
    DWORD offset = 0;
    ContextAddress org_addr0 = addr0;
    ContextAddress org_addr1 = addr1;

    if (ctx == NULL) err = ERR_INV_CONTEXT;
    else if (ctx->exited) err = ERR_ALREADY_EXITED;

    if (err == 0 && ctx->parent != NULL) ctx = ctx->parent;


    if(err == 0) {
        CodeArea area;

        memset(&area, 0, sizeof(area));

        line = CLIParser_GetLineFromAddress(addr0, &file);

        if(line == -1)
            return -1;

        area.file = file;
        area.start_line = line;
        area.start_address = addr0;
        area.end_line = line;
        area.end_address = addr1;
        callback(&area, user_args);
    }

    if (err != 0) {
        errno = err;
        return -1;
    }

    return 0;
}

void ini_line_numbers_lib(void) {
    //SymSetOptions(SymGetOptions() | SYMOPT_LOAD_LINES | SYMOPT_DEFERRED_LOADS);
#if ENABLE_LineNumbersMux
    add_line_numbers_reader(&line_numbers_reader);
#endif
}

#endif /* SERVICE_LineNumbers && !ENABLE_LineNumbersProxy && defined(_MSC_VER) && !ENABLE_ELF */
static void debug_event_handler(DDebugEvent * ddebug_event) {
    
    DDebugState * ddebug_state = ddebug_event->ddebug_state;

    DEVICE_EVENT * device_event = &ddebug_event->device_event;

    Context * ctxSib = context_find_from_pid(device_event->sibId, 0);
    Context * ctxDev = context_find_from_pid(device_event->devId, 1);
    ContextExtensionSib * dext = NULL;

    assert(ctxDev == NULL || ctxDev->parent == ctxSib);

    switch (device_event->debugEventCode) {

    case PROGRAMMING_SUCCEEDED:

        // Create context for SIB Server which is basically
        // a substitution of a parental process for the running
        // program on the device.

        assert(ctxSib == NULL);
        assert(ctxDev == NULL);

        ctxSib = create_context(pid2id(PSEUDO_PROCESS_ID,0));
        ctxSib->big_endian = 1; //big_endian_host();
        ctxSib->mem = ctxSib;
        ctxSib->mem_access |= MEM_ACCESS_INSTRUCTION;
        ctxSib->mem_access |= MEM_ACCESS_DATA;
        ctxSib->mem_access |= MEM_ACCESS_USER;

        dext = DEXT(ctxSib);        
        dext->pid = device_event->sibId; 
        dext->ddebug_state = ddebug_state;

        // Link context and send context-created event.
        link_context(ctxSib);
        send_context_created_event(ctxSib);

        // ----------
        ctxDev = create_context(pid2id(PSEUDO_MAINTHREAD_ID, device_event->sibId));

        dext        = DEXT(ctxDev);
        dext->regs  = (REG_SET*)loc_alloc_zero(sizeof(REG_SET));
        dext->pid   = PSEUDO_MAINTHREAD_ID;
       
        ctxDev->mem         = ctxSib;
        ctxDev->big_endian  = big_endian_host();
        ctxDev->parent      = ctxSib;
        ctxDev->parent->ref_count++;

        list_add_last(&ctxDev->cldl, &ctxSib->children);
        link_context(ctxDev);
        send_context_created_event(ctxDev);
        // ----------
        
        //dext->device_event = *device_event;
        send_context_changed_event(ctxSib);
        send_context_changed_event(ctxDev);

        break;

    case BREAKPOINT_REACHED:
        
        dext        = DEXT(ctxDev);
        memcpy(&dext->suspend_reason, &device_event->u.Exception, sizeof(EXCEPTION_DEVICE_DEBUG_INFO));

        dext->device_event = *device_event;
        ddebug_event->continue_status = event_sib_context_stopped(ctxDev);

        break;

    default:
        // This should not happen.
        printf("debug_event_handler() did not recognize the event\n");
        assert(1);
        break;
    }
}

Back to the top