2022-09-06 19:14:07 -04:00
|
|
|
|
// Copyright 2014 The Crashpad Authors
|
2014-11-04 12:36:29 -05:00
|
|
|
|
//
|
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
|
// you may not use this file except in compliance with the License.
|
|
|
|
|
// You may obtain a copy of the License at
|
|
|
|
|
//
|
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
//
|
|
|
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
|
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
|
// See the License for the specific language governing permissions and
|
|
|
|
|
// limitations under the License.
|
|
|
|
|
|
|
|
|
|
#include "minidump/minidump_thread_id_map.h"
|
|
|
|
|
|
|
|
|
|
#include <limits>
|
|
|
|
|
#include <set>
|
|
|
|
|
#include <utility>
|
|
|
|
|
|
2020-06-22 11:14:31 +02:00
|
|
|
|
#include "base/check_op.h"
|
2015-03-06 16:05:34 -08:00
|
|
|
|
#include "base/numerics/safe_conversions.h"
|
2014-11-04 12:36:29 -05:00
|
|
|
|
#include "snapshot/thread_snapshot.h"
|
|
|
|
|
|
|
|
|
|
namespace crashpad {
|
|
|
|
|
|
|
|
|
|
void BuildMinidumpThreadIDMap(
|
|
|
|
|
const std::vector<const ThreadSnapshot*>& thread_snapshots,
|
|
|
|
|
MinidumpThreadIDMap* thread_id_map) {
|
|
|
|
|
DCHECK(thread_id_map->empty());
|
|
|
|
|
|
|
|
|
|
// First, try truncating each 64-bit thread ID to 32 bits. If that’s possible
|
|
|
|
|
// for each unique 64-bit thread ID, then this will be used as the mapping.
|
|
|
|
|
// This preserves as much of the original thread ID as possible when feasible.
|
|
|
|
|
bool collision = false;
|
|
|
|
|
std::set<uint32_t> thread_ids_32;
|
|
|
|
|
for (const ThreadSnapshot* thread_snapshot : thread_snapshots) {
|
|
|
|
|
uint64_t thread_id_64 = thread_snapshot->ThreadID();
|
|
|
|
|
if (thread_id_map->find(thread_id_64) == thread_id_map->end()) {
|
2015-02-04 17:30:03 -08:00
|
|
|
|
uint32_t thread_id_32 = static_cast<uint32_t>(thread_id_64);
|
2015-03-31 14:29:32 -04:00
|
|
|
|
if (!thread_ids_32.insert(thread_id_32).second) {
|
2014-11-04 12:36:29 -05:00
|
|
|
|
collision = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
thread_id_map->insert(std::make_pair(thread_id_64, thread_id_32));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (collision) {
|
|
|
|
|
// Since there was a collision, go back and assign each unique 64-bit thread
|
|
|
|
|
// ID its own sequential 32-bit equivalent. The 32-bit thread IDs will not
|
|
|
|
|
// bear any resemblance to the original 64-bit thread IDs.
|
|
|
|
|
thread_id_map->clear();
|
|
|
|
|
for (const ThreadSnapshot* thread_snapshot : thread_snapshots) {
|
|
|
|
|
uint64_t thread_id_64 = thread_snapshot->ThreadID();
|
|
|
|
|
if (thread_id_map->find(thread_id_64) == thread_id_map->end()) {
|
2015-03-06 16:05:34 -08:00
|
|
|
|
uint32_t thread_id_32 =
|
|
|
|
|
base::checked_cast<uint32_t>(thread_id_map->size());
|
2014-11-04 12:36:29 -05:00
|
|
|
|
thread_id_map->insert(std::make_pair(thread_id_64, thread_id_32));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DCHECK_LE(thread_id_map->size(), std::numeric_limits<uint32_t>::max());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace crashpad
|