Hi,
with the perf.data from Youngjae (perf_etf1_v4_12.data) I get the following error (using the latest CoreSight decoder from commit a466eb8dc3ac2bb6d60f058464e13b006717a977 Author: Mike Leach mike.leach@linaro.org Date: Fri Aug 18 14:30:57 2017 +0100
and linux perf from commit e565ad632331f42059a14d486cd4d27477b8d20d Author: Stephen Boyd sboyd@codeaurora.org Date: Fri Jul 28 13:31:11 2017 -0700 )
(gdb) run inject -f -i perf_etf1_v4_12.data -o inj --itrace=i100usl --strip
Program received signal SIGSEGV, Segmentation fault. 0x0000ffffb73841e0 in EtmV4IPktProcImpl::processData (this=0xffffffff4ec0, index=0, dataBlockSize=1, pDataBlock=0x474e5543432b2b00 <error: Cannot access memory at address 0x474e5543432b2b00>, numBytesProcessed=0xffffb7384168 <EtmV4IPktProcImpl::processData(unsigned int, unsigned int, unsigned char const*, unsigned int*)+576>) at /root/etm/decoder-may/decoder/source/etmv4/trc_pkt_proc_etmv4i_impl.cpp:155
This problem was an exception throwBadSequenceError from the following code in EtmV4IPktProcImpl::extractCondResult
unsigned EtmV4IPktProcImpl::extractCondResult(const std::vector<uint8_t> &buffer, const unsigned st_idx, uint32_t& key, uint8_t &result) { unsigned idx = 0; bool lastByte = false; int incr = 0;
key = 0;
while(!lastByte && (idx < 6)) // cannot be more than 6 bytes for res + 32 bit key { if(buffer.size() > (st_idx + idx)) { if(idx == 0) { result = buffer[st_idx+idx]; key = (buffer[st_idx+idx] >> 4) & 0x7; incr+=3; } else { key |= ((uint32_t)(buffer[st_idx+idx] & 0x7F)) << incr; incr+=7; } idx++; lastByte = (bool)((buffer[st_idx+idx] & 0x80) == 0); } else { throwBadSequenceError("Invalid continuation fields in packet"); } } return idx; }
This function gets called with the following arguments: (gdb) p buffer $156 = std::vector of length 6, capacity 16 = {107 'k', 72 'H', 252 '\374', 247 '\367', 154 '\232', 79 'O'} (gdb) p st_idx $157 = 5
and remark that if we go and execute the code that computes lastByte, we access outside the allocated buffer, as idx is incremented from 0 before the access of buffer[st_idx+idx], so we try to access buffer[6] which is not allocated.
I would recommend changing this code like this:
--- a/decoder/source/etmv4/trc_pkt_proc_etmv4i_impl.cpp +++ b/decoder/source/etmv4/trc_pkt_proc_etmv4i_impl.cpp @@ -1521,8 +1521,8 @@ unsigned EtmV4IPktProcImpl::extractContField64(const std::vector<uint8_t> &buffe key |= ((uint32_t)(buffer[st_idx+idx] & 0x7F)) << incr; incr+=7; } - idx++; lastByte = (bool)((buffer[st_idx+idx] & 0x80) == 0); + idx++; } else {
which makes the decoder pass further without the segfault. Mike, do you think this is a good change to the decoder?
Thanks, Sebastian