crashpad/minidump/minidump_thread_name_list_writer.h
Ben Hamilton 339b125241 [minidump] Fix unaligned pointer in thread name list
https://crrev.com/c/3671775/ introduced a warning (and thus, a
compilation failure) on 32-bit ARM when taking the address of the RVA64
field MINIDUMP_THREAD_NAME::RvaOfThreadName:

minidump/minidump_thread_name_list_writer.cc:57:23: error: taking address of packed member 'RvaOfThreadName' of class or structure 'MINIDUMP_THREAD_NAME' may result in an unaligned pointer value [-Werror,-Waddress-of-packed-member]
  name_->RegisterRVA(&thread_name_.RvaOfThreadName);
                      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~

Indeed, MINIDUMP_THREAD_NAME's RvaOfThreadName field is not aligned,
so the technique used in MinidumpWritable::Register*() of passing in a
rawptr to an arbitrary struct field which is later dereferenced cannot
be used for this field.

This CL replaces the use of MinidumpWritable::Register*() with
overriding MinidumpThreadNameWriter::WillWriteAtOffsetImpl() to
directly calculate and assign thread_name_.RvaOfThreadName.

Change-Id: I71e751a5b5e896b5e7277879bdbdff6e9eefe023
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3693846
Reviewed-by: Mark Mentovai <mark@chromium.org>
Commit-Queue: Ben Hamilton <benhamilton@google.com>
Reviewed-by: Ben Hamilton <benhamilton@google.com>
2022-06-08 18:52:32 +00:00

111 lines
3.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Copyright 2022 The Crashpad Authors. All rights reserved.
//
// 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.
#ifndef CRASHPAD_MINIDUMP_MINIDUMP_THREAD_NAME_LIST_WRITER_H_
#define CRASHPAD_MINIDUMP_MINIDUMP_THREAD_NAME_LIST_WRITER_H_
#include <windows.h>
#include <dbghelp.h>
#include <stdint.h>
#include <sys/types.h>
#include <memory>
#include <vector>
#include "minidump/minidump_stream_writer.h"
#include "minidump/minidump_string_writer.h"
#include "minidump/minidump_writable.h"
namespace crashpad {
//! \brief The writer for a MINIDUMP_THREAD_NAME object in a minidump file.
//!
//! Because MINIDUMP_THREAD_NAME objects only appear as elements of
//! MINIDUMP_THREAD_NAME_LIST objects, this class does not write any data on its
//! own. It makes its MINIDUMP_THREAD_NAME data available to its
//! MinidumpThreadNameListWriter parent, which writes it as part of a
//! MINIDUMP_THREAD_NAME_LIST.
class MinidumpThreadNameWriter final : public internal::MinidumpWritable {
public:
MinidumpThreadNameWriter();
MinidumpThreadNameWriter(const MinidumpThreadNameWriter&) = delete;
MinidumpThreadNameWriter& operator=(const MinidumpThreadNameWriter&) = delete;
~MinidumpThreadNameWriter() override;
//! \brief Returns a MINIDUMP_THREAD_NAME referencing this objects data.
//!
//! This method is expected to be called by a MinidumpThreadNameListWriter in
//! order to obtain a MINIDUMP_THREAD_NAME to include in its list.
//!
//! \note Valid in #kStateWritable.
const MINIDUMP_THREAD_NAME* MinidumpThreadName() const;
//! \brief Sets MINIDUMP_THREAD_NAME::ThreadId.
void SetThreadId(uint32_t thread_id) { thread_name_.ThreadId = thread_id; }
//! \brief Sets MINIDUMP_THREAD_NAME::RvaOfThreadName.
void SetThreadName(const std::string& thread_name);
private:
// MinidumpWritable:
size_t SizeOfObject() override;
std::vector<MinidumpWritable*> Children() override;
bool WillWriteAtOffsetImpl(FileOffset offset) override;
bool WriteObject(FileWriterInterface* file_writer) override;
MINIDUMP_THREAD_NAME thread_name_;
std::unique_ptr<internal::MinidumpUTF16StringWriter> name_;
};
//! \brief The writer for a MINIDUMP_THREAD_NAME_LIST stream in a minidump file,
//! containing a list of MINIDUMP_THREAD_NAME objects.
class MinidumpThreadNameListWriter final
: public internal::MinidumpStreamWriter {
public:
MinidumpThreadNameListWriter();
MinidumpThreadNameListWriter(const MinidumpThreadNameListWriter&) = delete;
MinidumpThreadNameListWriter& operator=(const MinidumpThreadNameListWriter&) =
delete;
~MinidumpThreadNameListWriter() override;
//! \brief Adds a MinidumpThreadNameWriter to the MINIDUMP_THREAD_LIST.
//!
//! This object takes ownership of \a thread_name and becomes its parent in
//! the overall tree of internal::MinidumpWritable objects.
//!
//! \note Valid in #kStateMutable.
void AddThreadName(std::unique_ptr<MinidumpThreadNameWriter> thread_name);
private:
// MinidumpWritable:
bool Freeze() override;
size_t SizeOfObject() override;
std::vector<MinidumpWritable*> Children() override;
bool WriteObject(FileWriterInterface* file_writer) override;
// MinidumpStreamWriter:
MinidumpStreamType StreamType() const override;
std::vector<std::unique_ptr<MinidumpThreadNameWriter>> thread_names_;
MINIDUMP_THREAD_NAME_LIST thread_name_list_;
};
} // namespace crashpad
#endif // CRASHPAD_MINIDUMP_MINIDUMP_THREAD_NAME_LIST_WRITER_H_