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
Date: Fri Aug 18 14:30:57 2017 +0100
and linux perf from
commit e565ad632331f42059a14d486cd4d27477b8d20d
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