Return-Path: X-Original-To: apmail-mesos-dev-archive@www.apache.org Delivered-To: apmail-mesos-dev-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id E986618645 for ; Fri, 4 Dec 2015 20:04:37 +0000 (UTC) Received: (qmail 99682 invoked by uid 500); 4 Dec 2015 20:04:37 -0000 Delivered-To: apmail-mesos-dev-archive@mesos.apache.org Received: (qmail 99592 invoked by uid 500); 4 Dec 2015 20:04:37 -0000 Mailing-List: contact dev-help@mesos.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@mesos.apache.org Delivered-To: mailing list dev@mesos.apache.org Received: (qmail 99580 invoked by uid 99); 4 Dec 2015 20:04:37 -0000 Received: from Unknown (HELO spamd3-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 04 Dec 2015 20:04:37 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd3-us-west.apache.org (ASF Mail Server at spamd3-us-west.apache.org) with ESMTP id C8280180A75 for ; Fri, 4 Dec 2015 20:04:36 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd3-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: 2.898 X-Spam-Level: ** X-Spam-Status: No, score=2.898 tagged_above=-999 required=6.31 tests=[DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, HTML_MESSAGE=3, RCVD_IN_MSPIKE_H2=-0.001, SPF_PASS=-0.001] autolearn=disabled Authentication-Results: spamd3-us-west.apache.org (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.com Received: from mx1-us-east.apache.org ([10.40.0.8]) by localhost (spamd3-us-west.apache.org [10.40.0.10]) (amavisd-new, port 10024) with ESMTP id FoIU6582EyxM for ; Fri, 4 Dec 2015 20:04:33 +0000 (UTC) Received: from mail-ob0-f176.google.com (mail-ob0-f176.google.com [209.85.214.176]) by mx1-us-east.apache.org (ASF Mail Server at mx1-us-east.apache.org) with ESMTPS id 748E642AD4 for ; Fri, 4 Dec 2015 20:04:33 +0000 (UTC) Received: by obbww6 with SMTP id ww6so80784563obb.0 for ; Fri, 04 Dec 2015 12:04:27 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type; bh=BhQ5KUolq8HR6cA3HZM3/TnbjGBHr0QaI6+cvcyR3Hs=; b=k9BTLKnlt3W7imE5J0hsV0ezhyqid2u0K0MwZjcmPrS4tcahym74lO9eC2hj353yMb 4XOQL6Ed7OQAXltttHHONNMUzOkO+THDkTls6ob3PwzliZuLHLT8JbEHgqdBg/cD8dQT 3brCOzf3Z8letWa5Wo0mVxmWba6SWfiaqXqeTfcN+2wwc9eslW7VJqvHTRdBdRQ9QyTa O8QzEe0bmPEOSIvlaVYN+yLW4HwMSv1HLWvZVNwXRFpQcBPgrvGfODS6fgcE1J+r/6jZ lNnTI2ejtnHYIUFb7MM0HiK3Xc4vm+lcQDVFsSKvKIg75yveMdg89c67Slmpz3UuL0hq shAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-type; bh=BhQ5KUolq8HR6cA3HZM3/TnbjGBHr0QaI6+cvcyR3Hs=; b=De7EmjomHh6VlIoNbw5p+QnQE9GphtcqgsZ+Ipyd5V1QLWNPsw4wkaDZ8sDg50U32W 5c6lWqsh9QmZhMmI08kZIP3zoBmYw6ETYgKHN8NHHAEu7Q8ENk4A5czUmBAveXe3v7td v8CskX8kMrCwQQqHkvZPIeIRNL1dlkp307TO3E+oePh9nJsgD1GhfW5zgDUU1S0PF3cz ws8FGjhfH7fC8WfFKm4Y59kpl2k+YHjZrg7F59pr5dQA6BTFAobceKXITquIlm+5ei3I QjP5q93c/StYAjKhVhvtQuhEtwxTxIkbODnUOwRXvd2zsQvyqVRQ6HtcF0YrJSVESU8x ZRgg== X-Received: by 10.182.74.226 with SMTP id x2mr11044364obv.87.1449259467351; Fri, 04 Dec 2015 12:04:27 -0800 (PST) Received: from mail-ob0-f178.google.com (mail-ob0-f178.google.com. [209.85.214.178]) by smtp.gmail.com with ESMTPSA id j7sm6368246oeq.0.2015.12.04.12.04.26 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Fri, 04 Dec 2015 12:04:26 -0800 (PST) Received: by obcse5 with SMTP id se5so77400417obc.3 for ; Fri, 04 Dec 2015 12:04:26 -0800 (PST) X-Gm-Message-State: ALoCoQnMGkqVR6H8JZ4qaaJpZpDnhkQ+TkUCtgsZV9eBdcbKbINohygOtgIy67TrIbhNhh66fAD1 X-Received: by 10.60.54.168 with SMTP id k8mr14567378oep.51.1449259466546; Fri, 04 Dec 2015 12:04:26 -0800 (PST) MIME-Version: 1.0 Received: by 10.76.8.42 with HTTP; Fri, 4 Dec 2015 12:04:06 -0800 (PST) In-Reply-To: References: <544a236de9d64657b195122b7f68957b@git.apache.org> From: Benjamin Mahler Date: Fri, 4 Dec 2015 12:04:06 -0800 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: mesos git commit: Fixed pointer alignment error in IP::create(). To: dev Cc: Neil Conway , Michael Park , commits@mesos.apache.org Content-Type: multipart/alternative; boundary=089e01160600b0fae0052618034e --089e01160600b0fae0052618034e Content-Type: text/plain; charset=UTF-8 Sorry, the first example from protobuf_utils.cpp isn't so bad, although we're inconsistent with how we name iterators. Also, it would be great to use foreach with a reversed adaptor rather than manual reverse iteration. On Fri, Dec 4, 2015 at 12:01 PM, Benjamin Mahler wrote: > (Hm.. were you using bold formatting here? Apache's mail servers will > strip it and change it into *asterisks*.) > > Yes, in general we want to be conservative with auto, and a lot of > additions got through review that should not have. For example: > > src/common/protobuf_utils.cpp: for (auto status = > task.statuses().rbegin(); > src/local/local.cpp: auto authorizerNames = > strings::split(flags.authorizers, ","); > src/master/http.cpp: auto ids = > ::protobuf::parse>(jsonIds.get()); > src/slave/containerizer/mesos/provisioner/docker/token_manager.cpp: > const auto padding = segment.length() % 4; > src/tests/fault_tolerance_tests.cpp: auto capabilityType = > FrameworkInfo::Capability::REVOCABLE_RESOURCES; > > These definitely do not fit with our style guidelines around improving > readability. The potential traps you've described are even more reason to > be conservative with auto usage in our project. > > In many of these cases, the type is not obvious from the right-hand-side. > If the person reading the code has to think in order to figure out what > 'auto' is, we shouldn't be using it. My big concern here is that we need to > make it as easy as possible to read and understand the code. > > Also, if the type is not onerous, why be aggressive with 'auto'? > > On Fri, Dec 4, 2015 at 1:10 AM, Michael Park wrote: > >> Ah, I didn't realize the current wording of the *auto* use cases were that >> strict. But let me explain, and see what you and others think. >> >> First off, we already have uses of *const auto* and *const **auto&* in the >> codebase. From my reading, it seems that you feel the same way about them >> as you do towards *auto** (correct me if I'm reading wrong). I think >> >> The deduction rules for *auto* are equivalent to template argument >> deduction rules. One must know and understand that fact in order to use >> *auto* correctly. Given *auto x = expr;* one may "intuitively" think that >> *auto *simply takes on the exact type of the right hand side, which is not >> what happens (we have *decltype(auto)* for that). So I don't agree that >> *auto&* and *auto** are any less intuitive than *auto*. >> >> IMO, it follows that the guideline for the qualifiers surrounding *auto* >> is >> equivalent to the guideline for qualifiers surrounding a template >> parameter. >> >> * template void F(T x);* *F(expr); *an argument of >> arbitrary >> type by value, *auto x = expr;* >> * template void F(const T& x); F(expr);* an argument of >> arbitrary type by const-ref *const auto& x = expr;* >> * template void F(const T* x); F(expr);* an argument of >> arbitrary type, const-pointer *const auto* x = expr;* >> ... >> >> In the case being considered, we could have simply used *auto* because a >> decaying a pointer has no effect (I don't think this is obvious). >> >> * auto ptr = static_cast(&t);* >> // *const T** decayed is *const T**, so *ptr* is *const T** and we're >> ok. >> >> However, consider how a seemingly innocent modification can become >> incorrect with an assumption that *auto* simply takes the exact type of >> the >> right hand side: >> >> *auto ref = static_cast(t);* >> // incorrect assumption: type of *ref* is *const T&* >> *const T* ptr = &ref;* >> // incorrect assumption: *ptr == &t* >> >> We actually need: *const auto& ref = static_cast(t);* in order >> for *ptr == &t* to be true. With that in mind, I would prefer to write the >> above code as: >> >> *const auto* ptr = static_cast(&t);* >> >> and the innocent-looking modification as: >> >> *const auto& ref = static_cast(t);* >> * const T* ptr = &ref;* >> >> Thanks, >> >> MPark. >> >> On Thu, Dec 3, 2015 at 10:20 PM Benjamin Mahler < >> benjamin.mahler@gmail.com> >> wrote: >> >> > Why did you guys choose to use 'auto*' here? These are the first >> instances >> > in the code base, can we remove them? Let's consider 'auto&' and 'auto*' >> > and update the style guide first, IMHO 'auto*' and 'auto&' are less >> > intuitive, so we may want to be more conservative about them in general. >> > >> > On Thu, Dec 3, 2015 at 12:39 AM, wrote: >> > >> > > Repository: mesos >> > > Updated Branches: >> > > refs/heads/master 0a82c2b12 -> 49d3cb112 >> > > >> > > >> > > Fixed pointer alignment error in IP::create(). >> > > >> > > The previous code took the address of a `struct sockaddr`, and then >> cast >> > > the >> > > resulting pointer to `struct sockaddr_storage *`. The alignment >> > > requirements >> > > for `struct sockaddr_storage *` are more strict than for `struct >> sockaddr >> > > *`, >> > > and hence this code produced undefined behavior per ubsan in GCC 5.2. >> > > >> > > Drive-by Fix: Updated the code to use `reinterpret_cast` rather than a >> > > C-style >> > > cast, and to preserve constness. >> > > >> > > Review: https://reviews.apache.org/r/40435 >> > > >> > > >> > > Project: http://git-wip-us.apache.org/repos/asf/mesos/repo >> > > Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/49d3cb11 >> > > Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/49d3cb11 >> > > Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/49d3cb11 >> > > >> > > Branch: refs/heads/master >> > > Commit: 49d3cb1125cfcc8644e7f37b8d8654729aecd657 >> > > Parents: 0a82c2b >> > > Author: Neil Conway >> > > Authored: Thu Dec 3 03:13:22 2015 -0500 >> > > Committer: Michael Park >> > > Committed: Thu Dec 3 03:21:50 2015 -0500 >> > > >> > > ---------------------------------------------------------------------- >> > > .../3rdparty/stout/include/stout/ip.hpp | 39 >> > ++++++++++++++------ >> > > 1 file changed, 27 insertions(+), 12 deletions(-) >> > > ---------------------------------------------------------------------- >> > > >> > > >> > > >> > > >> > >> http://git-wip-us.apache.org/repos/asf/mesos/blob/49d3cb11/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp >> > > ---------------------------------------------------------------------- >> > > diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp >> > > b/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp >> > > index 3e506e1..1d34d4e 100644 >> > > --- a/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp >> > > +++ b/3rdparty/libprocess/3rdparty/stout/include/stout/ip.hpp >> > > @@ -211,23 +211,38 @@ inline Try IP::parse(const std::string& >> value, >> > > int family) >> > > >> > > inline Try IP::create(const struct sockaddr_storage& _storage) >> > > { >> > > - switch (_storage.ss_family) { >> > > - case AF_INET: { >> > > - struct sockaddr_in addr = *((struct sockaddr_in*) &_storage); >> > > - return IP(addr.sin_addr); >> > > - } >> > > - default: { >> > > - return Error( >> > > - "Unsupported family type: " + >> > > - stringify(_storage.ss_family)); >> > > - } >> > > - } >> > > + // According to POSIX: (IEEE Std 1003.1, 2004) >> > > + // >> > > + // (1) `sockaddr_storage` is "aligned at an appropriate boundary so >> > that >> > > + // pointers to it can be cast as pointers to protocol-specific >> address >> > > + // structures and used to access the fields of those structures >> > without >> > > + // alignment problems." >> > > + // >> > > + // (2) "When a `sockaddr_storage` structure is cast as a `sockaddr` >> > > + // structure, the `ss_family` field of the `sockaddr_storage` >> > structure >> > > + // shall map onto the `sa_family` field of the `sockaddr` >> structure." >> > > + // >> > > + // Therefore, casting from `const sockaddr_storage*` to `const >> > > sockaddr*` >> > > + // (then subsequently dereferencing the `const sockaddr*`) should >> be >> > > safe. >> > > + // Note that casting in the reverse direction (`const sockaddr*` to >> > > + // `const sockaddr_storage*`) would NOT be safe, since the former >> > might >> > > + // not be aligned appropriately. >> > > + const auto* addr = reinterpret_cast> > sockaddr*>(&_storage); >> > > + return create(*addr); >> > > } >> > > >> > > >> > > inline Try IP::create(const struct sockaddr& _storage) >> > > { >> > > - return create(*((struct sockaddr_storage*) &_storage)); >> > > + switch (_storage.sa_family) { >> > > + case AF_INET: { >> > > + const auto* addr = reinterpret_cast> > > sockaddr_in*>(&_storage); >> > > + return IP(addr->sin_addr); >> > > + } >> > > + default: { >> > > + return Error("Unsupported family type: " + >> > > stringify(_storage.sa_family)); >> > > + } >> > > + } >> > > } >> > > >> > > >> > > >> > > >> > >> > > --089e01160600b0fae0052618034e--