git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v2 3/4] strbuf_setlen: don't write to strbuf_slopbuf

From
Brandon Casey <drafnel@gmail.com>
Date
Aug 24, 2017, 18:29 UTC
Message-ID
<CA+sFfMdYXDt2mgnWq-HQQyBsCqYZ+689BCKEOw7siGjQoUysjg@mail.gmail.com>
In-Reply-To
<xmqqpobkx610.fsf@gitster.mtv.corp.google.com>
On Thu, Aug 24, 2017 at 9:52 AM, Junio C Hamano <gitster@pobox.com> wrote:
Show 11 quoted lines
> Brandon Casey <drafnel@gmail.com> writes:
>
>> Ah, you probably meant something like this:
>>
>>    const char strbuf_slopbuf = '\0';
>>
>> which gcc will apparently place in the read-only segment.  I did not know that.
>
> Yes but I highly suspect that it would be very compiler dependent
> and not something the language lawyers would recommend us to rely
> on.

I think compilers may have the option of placing variables that are explicitly initialized to zero in the bss segment too, in addition to those that are not explicitly initialized. So I agree that no one should write code that depends on their variables being placed in one segment or the other, but I could see someone using this behavior as an additional safety check; kind of a free assert, aside from the additional space in the .rodata segment.

> My response was primarily to answer "why?" with "because we did not
> bother".  The above is a mere tangent, i.e. "multiple copies of
> empty strings is a horrible implementation (and there would be a way
> to do it with a single instance)".

Merely adding const to our current strbuf_slopbuf declaration does not buy us anything since it will be allocated in r/w memory. i.e. it would still be possible to modify it via the buf member of strbuf. So you can't just do this:

   const char strbuf_slopbuf[1];

That's pretty much equivalent to what we currently have since it only restricts modifying the contents of strbuf_slopbuf directly through the strbuf_slopbuf variable, but it does not restrict modifying it through a pointer to that object.

Until yesterday, I was under the impression that the only way to access data in the rodata segment was through a constant literal. So my initial thought was that we could do something like:

   const char * const strbuf_slopbuf = "";
..but that variable cannot be used in a static assignment like:
   struct strbuf foo = {0, 0, (char*) strbuf_slopbuf};

So it seemed like our only option was to use a literal "" everywhere instead of a slopbuf variable _if_ we wanted to have the guarantee that our "slopbuf" could not be modified.

But what I learned yesterday, is that at least gcc/clang will place the entire variable in the rodata segment if the variable is both marked const _and_ initialized.

i.e. this will be allocated in the .rodata segment:
   const char strbuf_slopbuf[1] = "";
Show 8 quoted lines
>>    #define STRBUF_INIT  { .alloc = 0, .len = 0, .buf = (char*) &strbuf_slopbuf }
>>
>> respectively.  Yeah, that's definitely preferable to a macro.
>> Something similar could be done in object.c.
>
> What is the main objective for doing this change?  The "make sure we
> do not write into that slopbuf" assert() bothers you and you want to
> replace it with an address in the read-only segment?

Actually nothing about the patch bothers me. The point of that patch is to make sure we don't accidentally modify the slopbuf. I was just looking for a way for the compiler to help out and wondering if there was a reason we didn't attempt to do so in the first place.

I think the main takeaway here is that I learned something yesterday :-) I didn't actually intend to submit a patch for any of this, but if anything useful came out of the discussion I thought Martin may incorporate it into his patch if he wanted to.

-Brandon
Previous: Junio C HamanoNext: Martin Ågren
Message 58 of 64 in “Some ThreadSanitizer-results”
  1. 0/5 Some ThreadSanitizer-resultsMartin Ågren, Aug 15, 2017
  2. 1/5 convert: initialize attr_action in convert_attrsMartin Ågren, Aug 15, 2017
  3. Torsten BögershausenAug 15, 2017
  4. Torsten BögershausenAug 15, 2017
  5. Martin ÅgrenAug 15, 2017
  6. 2/5 pack-objects: take lock before accessing `remaining`Martin Ågren, Aug 15, 2017
  7. Johannes SixtAug 15, 2017
  8. 5/5 ThreadSanitizer: add suppressionsMartin Ågren, Aug 15, 2017
  9. tsan: t3008: hashmap_add touches size from multiple threadsMartin Ågren, Aug 15, 2017
  10. Jeff HostetlerAug 15, 2017
  11. Stefan BellerAug 15, 2017
  12. Martin ÅgrenAug 15, 2017
  13. Stefan BellerAug 15, 2017
  14. Martin ÅgrenAug 15, 2017
  15. Jeff HostetlerAug 15, 2017
  16. hashmap: address ThreadSanitizer concernsJeff Hostetler, Aug 30, 2017
  17. hashmap: add API to disable item counting when threadedJeff Hostetler, Aug 30, 2017
  18. Johannes SchindelinSep 1, 2017
  19. Jonathan NiederSep 1, 2017
  20. Jeff HostetlerSep 5, 2017
  21. Martin ÅgrenSep 5, 2017
  22. Jeff KingSep 2, 2017
  23. Johannes SchindelinSep 4, 2017
  24. Jeff HostetlerSep 5, 2017
  25. Junio C HamanoSep 6, 2017
  26. Jeff HostetlerSep 5, 2017
  27. Jeff KingSep 2, 2017
  28. Jeff HostetlerSep 5, 2017
  29. Simon RuderichSep 2, 2017
  30. Junio C HamanoSep 6, 2017
  31. Jeff HostetlerSep 6, 2017
  32. hashmap: address ThreadSanitizer concernsJeff Hostetler, Sep 6, 2017
  33. hashmap: add API to disable item counting when threadedJeff Hostetler, Sep 6, 2017
  34. tsan: t5400: set_try_to_free_routineMartin Ågren, Aug 15, 2017
  35. Stefan BellerAug 15, 2017
  36. Martin ÅgrenAug 15, 2017
  37. Jeff KingAug 17, 2017
  38. 4/5 strbuf_reset: don't write to slopbuf with ThreadSanitizerMartin Ågren, Aug 15, 2017
  39. Junio C HamanoAug 15, 2017
  40. Martin ÅgrenAug 15, 2017
  41. Junio C HamanoAug 15, 2017
  42. 3/5 Makefile: define GIT_THREAD_SANITIZERMartin Ågren, Aug 15, 2017
  43. Jeff KingAug 20, 2017
  44. Martin ÅgrenAug 20, 2017
  45. 0/4 Some ThreadSanitizer-resultsMartin Ågren, Aug 21, 2017
  46. 1/4 convert: always initialize attr_action in convert_attrsMartin Ågren, Aug 21, 2017
  47. 2/4 pack-objects: take lock before accessing `remaining`Martin Ågren, Aug 21, 2017
  48. 3/4 strbuf_setlen: don't write to strbuf_slopbufMartin Ågren, Aug 21, 2017
  49. Junio C HamanoAug 23, 2017
  50. Martin ÅgrenAug 23, 2017
  51. Junio C HamanoAug 23, 2017
  52. Brandon CaseyAug 23, 2017
  53. Junio C HamanoAug 23, 2017
  54. Brandon CaseyAug 23, 2017
  55. Brandon CaseyAug 23, 2017
  56. Brandon CaseyAug 23, 2017
  57. Junio C HamanoAug 24, 2017
  58. Brandon CaseyAug 24, 2017
  59. Martin ÅgrenAug 24, 2017
  60. Junio C HamanoAug 23, 2017
  61. Brandon CaseyAug 23, 2017
  62. 4/4 ThreadSanitizer: add suppressionsMartin Ågren, Aug 21, 2017
  63. Jeff KingAug 25, 2017
  64. Jeff HostetlerAug 28, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.