Hi Zied, On Mon, 2 Nov 2020 at 15:52, Zied Guermazi <zied.guerm...@trande.de> wrote: > > hi > > Thanks Mike for your support, it was very helpful. > > to put everything together, on arm, gdb inserts a sw breakpoint by patching > the code with an undefined instruction ( see comments in arm-tdep.c > line7687) when a breakpoint is hit, an exception number 9 "Undefined > Instruction exception" is raised and a branch packet with this info is > generated in etm traces, the trap is get handled by the kernel and it sends > the appropriate signal to gdb process. >
Looks like that code was designed for very early architectures. I wonder if it should not use the architected BKPT instruction when available (arch v5T onwards I think). > when the user continues the execution, gdb patches back the code and executes > the instruction. this leads to the instruction traced twice with an exception > in between, the same happens for next executed instruction > > here is the log of decoded packets > > [btrace] [ftrace] update insn: fun = main, file = ./function_call_history.c, > level = 0, insn = [1; 2) > cs_etm_decoder_trace_element_callback: elem->elem_type > OCSD_GEN_TRC_ELEM_INSTR_RANGE <= first execution attempt that raises an > undefined instruction exception > trace_chan_id: 18 > isa: CS_ETM_ISA_T32 > start addr = 0x400534 > end addr = 0x400536 > instructions count = 1 > last_i_type: OCSD_INSTR_OTHER > last_i_subtype: OCSD_S_INSTR_NONE > last instruction was executed > last instruction size: 2 > [btrace] [ftrace] update insn: fun = main, file = ./function_call_history.c, > level = 0, insn = [1; 3) > cs_etm_decoder_trace_element_callback: elem->elem_type > OCSD_GEN_TRC_ELEM_EXCEPTION <= the exception is traced > trace_chan_id: 18 > exception number: 9 <= undefined instruction exception > cs_etm_decoder_trace_element_callback: elem->elem_type > OCSD_GEN_TRC_ELEM_TRACE_ON > cs_etm_decoder_trace_element_callback: elem->elem_type > OCSD_GEN_TRC_ELEM_PE_CONTEXT > cs_etm_decoder_trace_element_callback: elem->elem_type > OCSD_GEN_TRC_ELEM_INSTR_RANGE <= execution of the original instruction > trace_chan_id: 18 > isa: CS_ETM_ISA_T32 > start addr = 0x400534 > end addr = 0x400536 > instructions count = 1 > last_i_type: OCSD_INSTR_OTHER > last_i_subtype: OCSD_S_INSTR_NONE > last instruction was executed > last instruction size: 2 > > as the code was changed during execution, it can not be reconstructed during > traces decoding. > > in addition, and for tracing applications running on Linux, we are not > interested in capturing raised exceptions, we can consider rolling back last > instruction in ftraces. As this is not obvious, we can consider ignoring the > repeated instruction as a workaround. > > for tracing bare metal software, we need to keep tracing exception, so we can > have a flag for ignoring exceptions, and activate or dis-activate it > according to the context. > > what do you think about it, shall I go for implementing it as described above? > > I assume that in this scenario, trace collection is ongoing over the BKPT hit / restart sequence and is decoded at some point later. Otherwise spotting the breakpoint would be easy. I cannot think of many circumstances where an instruction would be executed - or appear to be executed in the trace twice in succession* - other than being restarted after an exception. This debug case is one of those occasions - I would check that there are not other exceptions that might mimic this. Other than that it would appear that the execute / exception / execute again pattern can be used to spot a break and the 1st execute could be dropped since this was the breakpoint. If it was set on a conditional then you are interested in the actual trace result which could be either executed or not. Regards Mike * branch to self might appear like this, as would setting the trace address filters to a include just single instruction - but there would be no intervening exceptions in these cases. > Kind Regards > > Zied Guermazi > > > > On 02.11.20 12:59, Mike Leach wrote: > > Hi Zeid, > > On Sat, 31 Oct 2020 at 23:11, Zied Guermazi <zied.guerm...@trande.de> wrote: > > hi, > > while testing the implementation in gdb of branch tracing on arm > processors using etm, I faced the the situation where a breakpoint was > set, was hit and then the execution of the program was continued. While > decoding generated traces, I got the address of the breakpoint > (0x400552) executed twice, and then the following address (0x400554) > also executed twice. the instruction at (0x400554) is a BL ( a function > call) and the second execution corrupts the function history. > > here is a dump of generated trace elements > > > --------------------------------- > trace_chan_id: 18 > isa: CS_ETM_ISA_T32 > start addr = 0x400552 > end addr = 0x400554 > instructions count = 1 > last_i_type: OCSD_INSTR_OTHER > last_i_subtype: OCSD_S_INSTR_NONE > last instruction was executed > last instruction size: 2 > --------------------------------- > trace_chan_id: 18 > isa: CS_ETM_ISA_T32 > start addr = 0x400552 > end addr = 0x400554 > instructions count = 1 > last_i_type: OCSD_INSTR_OTHER > last_i_subtype: OCSD_S_INSTR_NONE > last instruction was executed > last instruction size: 2 > --------------------------------- > trace_chan_id: 18 > isa: CS_ETM_ISA_T32 > start addr = 0x400554 > end addr = 0x400558 > instructions count = 1 > last_i_type: OCSD_INSTR_BR > last_i_subtype: OCSD_S_INSTR_BR_LINK > last instruction was executed > last instruction size: 4 > --------------------------------- > trace_chan_id: 18 > isa: CS_ETM_ISA_T32 > start addr = 0x400554 > end addr = 0x400558 > instructions count = 1 > last_i_type: OCSD_INSTR_BR > last_i_subtype: OCSD_S_INSTR_BR_LINK > last instruction was executed > last instruction size: 4 > > the explanation I have for this behavior is that : > > -when setting the software breakpoint, the memory content of the > instruction (at 0x400552) was altered to the instruction BKPT, > > -when the breakpoint was hit, the original opcode was set at (0x400552) > and a BKPT was set to the next instruction address (0x400554), then the > execution was continued > > -when the second breakpoint (0x400554) was hit, the a BKPT opcode was > set at (0x400552) and the original opcode was set at (0x400554) then the > execution was continued > > I am using the function "int target_read_code (CORE_ADDR memaddr, > gdb_byte *myaddr, ssize_t len)" to give program memory content to the > decoder. so the collected etm traces are correct, but, as memory was > altered in between, the decoder is "cheated". > > I need to identify the re-execution of code due to breakpoint handling, > and roll back its impact on etm decoding. > > is there a mean to get the actual content of program memory including > patched addresses? > > is there a means of getting the history of patched addresses during the > debugging of a program? > > what is the type and subtype of a BKPT instruction in a decoded trace > elements? > > I can only really comment on this question. The type / subtype > information in the output from the decoder is generated from the > decoder walking the memory image of the executed trace - not from the > trace packets themselves. > The decoder classifies instructions according to how they will affect > trace flow with the "other" category being set for the majority of > instructions. The categories are: other, branch, indirect branch, ISB > / DSB / DMB / WFI / WFE. > These are important in program flow trace (PTM 1.x, ETM 4.x) as these > determine which instruction we attach the E/N atoms to. BKPT will be > classified as "other", if it is seen, as it has no effect on normal > program flow. It will cause an exception which has a specific trace > packet format. > > Regards > > Mike > > > do you have any other idea for handling this situation? > > > I am attaching the source code of the program as well as the > disassembled binary. the code was compiled as an application running on > linux on an ARMv7 A (STM32MP157 SoC). the breakpoint was set at line 43 > in the source code (line 238 in the disassembled code) > > > Kind Regards > > Zied Guermazi > > _______________________________________________ > CoreSight mailing list > coresi...@lists.linaro.org > https://lists.linaro.org/mailman/listinfo/coresight > > -- Mike Leach Principal Engineer, ARM Ltd. Manchester Design Centre. UK _______________________________________________ linaro-toolchain mailing list linaro-toolchain@lists.linaro.org https://lists.linaro.org/mailman/listinfo/linaro-toolchain