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

Reply via email to