Re: [go-nuts] user process instruction pointer symbol lookup

2024-06-20 Thread Massimiliano Giovagnoli
Thank you all. I was looking at the same goal, having collected stack 
traces from eBPF helper with IPs.

With debug/elf I've been able to resolve symbols for the use cases I 
tested, thank you Ian.
In example the right symbol is the one that satisfy ip >= sym.Value  && ip 
< (sym.Value+sym.Size) (where sym comes from elfBinary.Symbols()).

Il giorno mercoledì 3 aprile 2024 alle 13:25:14 UTC+2 TheDiveO ha scritto:

> Thank you Ian!
>
> Not sure yet if I found something useful related to the real process 
> addresses/offsets, but at least the "bcc" sources have one 
> "bcc_elf_get_text_scn_info()" that returns the address and offset of the 
> ".text" section.
>
> On Tuesday, April 2, 2024 at 8:01:11 PM UTC+2 Ian Lance Taylor wrote:
>
>> On Tue, Apr 2, 2024 at 2:35 AM 'TheDiveO' via golang-nuts 
>>  wrote: 
>> > 
>> > On Linux, given an arbitrary binary executable with symbol information 
>> in the executable, how can I lookup an instruction pointer address to get 
>> the corresponding symbol name? 
>> > 
>> > The binary (and its process) isn't a Go binary, but any arbitrary 
>> executable. The stack unwinding has already been done, so I'm presented 
>> with a list of instruction pointer addresses (return addresses) which I 
>> need to convert to more useful symbol names. 
>> > 
>> > I've seen the stdlib's debug/elf package, but I lack the ELF knowledge 
>> to press the elf package's knobs in the right order. Any examples of how to 
>> use debug/elf, and is it even the right package to use in this case? 
>>
>> debug/elf is the package to use. You'll want to call the Symbols 
>> method and look through the Symbols for one whose Value is <= the PC 
>> you want while Value+Size is > the PC you want. 
>>
>> If you are looking at runtime PC's from a stack trace, be aware that 
>> on most systems these days programs are position-independent, so there 
>> will be an offset between the addresses in the binary and the 
>> addresses from the stack trace. I don't know offhand of a standard 
>> way to figure out that offset. 
>>
>> Ian 
>>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/1358fa4c-1c1a-426e-a859-37a2070fdaacn%40googlegroups.com.


[go-nuts] VS Code debugger running on Beaglebone Black

2024-06-20 Thread Daniel Jankins
HI,

I am running VS code with Remote-SSH connected to Beaglebone black.
Writing and compiling code is not a problem.  Up to now I have been
debugging with print statements. I would like to use the VS code debugger.
It looks like the Delve debugger does not support armv7l.

Does anybody know how to use the VS code debugger on a Beaglebone BLack?

Thank you

-- 
DanJ

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CACHdq70q_x5JVKNAsk3hhymJ-3wGE-kEt4p48H%3DynV-O5FJNDg%40mail.gmail.com.


[go-nuts] Re: Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread tapi...@gmail.com
see: https://github.com/golang/go/issues/65878

package main

var a, b [0]int
var p, q = &a, &b

func main() {
if (p == q) {
p, q = &a, &b
println(p == q) // false
}
}

On Thursday, June 20, 2024 at 12:59:43 AM UTC+8 Oliver Eikemeier wrote:

> I'm observing some strange behavior and could use some help understanding 
> it.
>
> The specification 
>  says: *“Pointers to distinct zero-size variables may or may not be 
> equal.”*
>
> With the following program (Go Playground 
> ):
> var ( a struct{} b struct{} eq = &a == &b ) func f1() { println("&a:", 
> &a) println("&b:", &b) println("&a == &b:", eq) } 
>
>
> I'll get
> &a: 0x537580 &b: 0x537580 &a == &b: false 
>
>
> Okay, a and b are empty structs, do not escape, so they share the same 
> address - fine. Also, some optimizer sees that a and b are different 
> variables, so their addresses must be different, and decides to make &a 
> == &b a constant - wrong, but I can live with that.
>
> My question would be: Is this behavior expected, somehow defined by the 
> specification, or is it undefined behavior?
>
> Let's try to confuse the optimizer a little (Go Playground 
> ):
> var ( a struct{} b struct{} aa = &a ba = &b eq = aa == ba ) func f1() { 
> println("&a:", aa) println("&b:", ba) println("&a == &b:", eq) } 
>
> results in
> &a: 0x5375a0 &b: 0x5375a0 &a == &b: true 
>
>
> Mission accomplished, too complicated to calculate in advance. But globals 
> are bad, so (Go Playground ):
> func f2() { var ( a struct{} b struct{} aa = &a ba = &b eq = aa == ba ) 
> println("&a:", aa) println("&b:", ba) println("&a == &b:", eq) } 
>
> &a: 0xc46740 &b: 0xc46740 &a == &b: false 
>
>
> Seems like inlining helps generate false answers.
>
> The interesting part here is that I can create two pointers (which may or 
> may not be equal per specification), but depending on how I compare them I 
> get different results.
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/dc252ba1-60dd-4e4c-add7-1dd8e39f12c3n%40googlegroups.com.


Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread 'Axel Wagner' via golang-nuts
I want to re-emphasise that both of these examples violate the allowed
usages of unsafe.Pointer defined by gc. So I would argue that, yes, its
expectation is reasonable, because it explicitly told you not to create
this situation.

If you can construct a program that does not violate the unsafe.Pointer
rules and yet behaves unexpectedly, the question might be more ambiguous.

On Thu 20. Jun 2024 at 16:18, Oliver Eikemeier 
wrote:

> Thanks for that example.
>
> The issue is that you and I have constructed aliased variables that the
> optimizer assumes are not aliased. Therefore the “false” on comparison,
> which also happens with pointers to zero-sized variables, but is much more
> common in the latter case.
>
> This is interesting. I’m not enough of a compiler buff to say that this
> assumption is reasonable - Go is 14 years old, so it seems to work - but
> obviously one can write code where it is false, the “zero-sized pointers”
> being the most prominent example. Anyone has a pointer to the alias
> analysis design of the Go compiler?
>
> Am 20.06.2024 um 15:57 schrieb Axel Wagner  >:
>
> I don't believe the issue in this case really is to do with zero-sized
> variables. Here is an example with the same output, not involving any
> zero-sized variables:
> https://go.dev/play/p/JzbwbVqBR0k
> The issue is that you treat a `*struct{}` as an `*int` - that is, you
> explicitly obtain a pointer to invalid memory - and then expect that to
> have any reasonable behaviour.
>
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAEkBMfGqXfeeU32z1tetauvH91u4iZSocKd3j2127tiSqGY2QQ%40mail.gmail.com.


Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread Oliver Eikemeier


> Am 20.06.2024 um 14:12 schrieb Axel Wagner :
> 
> On Thu, 20 Jun 2024 at 13:48, Oliver Eikemeier  > wrote:
> 
> I think you should acknowledge that the spec *is* already trying to be very 
> clear about this. The fact that you can poke holes in it is because writing a 
> spec unambiguously is hard.

I acknowledge that - that’s why I care in the first place and also - as 
mentioned - try not to be stubborn. Although the latter is not always easy in 
internet discussions, but I digress.

> But the two quoted phrases are there in the best attempt to clearly state 
> that you can not rely on any assumptions about pointers to zero-sized 
> variables - within the somewhat abstract framework of the spec. Feel free to 
> propose a better one, I'm not actually arguing against that.

Yeah, I’m still trying to understand the issue, the discussion helps, so thanks 
for that.

> Am 20.06.2024 um 14:21 schrieb Robert Engels :
> 
> I would add that I think the Go team should strive to remove as much 
> “implementation defined” or “undefined” from the spec as possible. Forgo the 
> optimizations. It’s this language that makes C++ such a pain to work with 
> especially in a cross platform manner.
> 
> I think you can safely narrow the spec in this area without issue - since it 
> would have been very difficult to use anyway. Maybe some highly specialized 
> code that relied on a particular Go implementation might. 

What happens seems to be:

a) In practice the runtime just uses pointers as memory addresses, so 
everything is fine there.

b) Pointers (especially unsafe pointers) being address in memory (not only “a 
storage location for holding a value”) is not really specified, but sometimes 
useful. The standard runtime uses casting of unsafe pointer for multiple 
reasons.

c) Pointers to zero sized variables have to point somewhere. Since the variable 
has zero size, some aliasing is easily possible.

d) The optimizer is free to make assumptions about aliasing that sometimes 
don’t match the memory alignment during runtime, disagreeing with a).

I’m not advocating against the optimizer making assumptions about aliasing that 
are not true, it seems useful to me.

On the other hand you can do surprising constructs (Go Playground 
):

func f7() {
var (
a  struct{}
b  int
aa = (*int)(unsafe.Pointer(&a))
ba = (*int)(unsafe.Pointer(&b))
)

println("&a:", aa, reflect.TypeOf(aa).String())
println("&b:", ba, reflect.TypeOf(ba).String())

*ba = 0

*aa++
println(*ba, aa == ba)

*ba++
println(*aa, ba == aa)
}

&a: 0xc466f8 *int
&b: 0xc466f8 *int
0 false
2 false

There are definitely dragons. I might need some more time to think over this, 
but thanks to every participant for the useful input.

Cheers
Oliver

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/E0D19A9C-4434-4CEB-B154-B10CD3959A61%40fillmore-labs.com.


Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread Robert Engels
What I asked did not require the first, I was referring more about the latter. So regardless of how it is implemented it is always false. On Jun 20, 2024, at 7:39 AM, Axel Wagner  wrote:On Thu, 20 Jun 2024 at 14:21, Robert Engels  wrote:I would add that I think the Go team should strive to remove as much “implementation defined” or “undefined” from the spec as possible. Forgo the optimizations. It’s this language that makes C++ such a pain to work with especially in a cross platform manner. I think you can safely narrow the spec in this area without issue - since it would have been very difficult to use anyway. Maybe some highly specialized code that relied on a particular Go implementation might. I strongly disagree. There is a lot of software out there that relies on zero-sized fields to achieve certain semantic behaviours (like preventing copying or using unkeyed struct literals) or alignments. They all assume that the size of a struct is not impacted by that. Without this "optimization" that would no longer be true and every zero-sized field must take at least one byte of memory, to be able to guarantee that they have different addresses. That is just not going to happen.On the other hand, removing the restriction in the other direction and just always making it false is what I suggested last time and there are reasons in that issue, why that isn't going to happen either. On Jun 20, 2024, at 7:12 AM, 'Axel Wagner' via golang-nuts  wrote:On Thu, 20 Jun 2024 at 13:48, Oliver Eikemeier  wrote:Am 20.06.2024 um 13:24 schrieb Axel Wagner :We can see that 1. `unsafe.Pointer` is definitionally a pointer type, 2. in your example, the two `unsafe.Pointers` do not point to the same variable and do not have the value `nil` and 3. are not pointing at distinct zero-sized variables. So their comparison should be `false`, which is what your example observes.Does it (Go Playground)?func f5() {	var (		a  struct{}		b  int		aa = (*int)(unsafe.Pointer(&a))		ba = (*int)(unsafe.Pointer(&b))		eq = aa == ba	)	println("&a:", aa, reflect.TypeOf(aa).String())	println("&b:", ba, reflect.TypeOf(ba).String())	println("&a == &b:", eq)	cmpIntPtr(aa, ba)}func cmpIntPtr(p1 *int, p2 *int) {	fmt.Println("p1 == p2:", p1 == p2)}&a: 0xc466f8 *int
&b: 0xc466f8 *int
&a == &b: false
p1 == p2: trueInterestingly, the spec does not forbid that (or specifies it as implementation-defined), though the (implementation-defined) unsafe.Pointer rules
 do, as using `unsafe.Pointer` to convert between pointers of different 
base types is only allowed if the target variable is at least as large 
as the source variable and both share an equivalent memory layout.I
 think the fact that the spec does not put any limits on the allowed 
behaviour of converting between `unsafe.Pointer` and other pointer types
 is a clear oversight that should be corrected (perhaps it should really
 be "The effect of converting between Pointer and uintptr is 
implementation-defined" should really say "and other types"). But I 
don't think it's a surprising fact that you can make a program behave in almost arbitrary ways by doing that. I’m advocating for at least a FAQ article,I tend to agree, though I'm not sure how to phrase that, beyond saying "do not make any assumptions about the identity pointers to zero-sized variables or with zero-sized base types or that where derived from one of those" and I'm not sure how helpful that is.It seems like a frequently asked question to me ;)It is. But note that every time it is asked, it leads to considerable discussion, which seems to strongly suggest that it is hard to give a simple, unambiguous answer that people find satisfying.I think you should acknowledge that the spec *is* already trying to be very clear about this. The fact that you can poke holes in it is because writing a spec unambiguously is hard. But the two quoted phrases are there in the best attempt to clearly state that you can not rely on any assumptions about pointers to zero-sized variables - within the somewhat abstract framework of the spec. Feel free to propose a better one, I'm not actually arguing against that.And I'm also not arguing against an FAQ entry. Ideally, someone would suggest a phrasing that is sufficiently broad and unambiguous and clear to cover any version of this question people might ask, while also not contradicting the spec. but also think the specification should be adapted, for clarity but also for the fact that only one pointer pointing to a zero-sized variable can compare differently to anything over time, even things having the same address value.Note that "address value" is not something that exists within the spec. As for clarifying the spec here, maybe. I do think the behavior is covered, as I outlined above. And as above, I'm not sure how to clarify it further, while still leaving up the space we want to left open.I vot

Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread 'Axel Wagner' via golang-nuts
FYI, filed https://github.com/golang/go/issues/68086 for the spec-hole that
conversions between unsafe.Pointer and other pointer types are not
implementation defined.

On Thu, 20 Jun 2024 at 14:12, Axel Wagner 
wrote:

>
>
> On Thu, 20 Jun 2024 at 13:48, Oliver Eikemeier <
> eikeme...@fillmore-labs.com> wrote:
>
>>
>> Am 20.06.2024 um 13:24 schrieb Axel Wagner > >:
>>
>> We can see that 1. `unsafe.Pointer` is definitionally a pointer type, 2.
>> in your example, the two `unsafe.Pointers` do not point to the same
>> variable and do not have the value `nil` and 3. are not pointing at
>> distinct zero-sized variables. So their comparison should be `false`, which
>> is what your example observes.
>>
>>
>> Does it (Go Playground )?
>>
>> func f5() {
>> var (
>> a  struct{}
>> b  int
>> aa = (*int)(unsafe.Pointer(&a))
>> ba = (*int)(unsafe.Pointer(&b))
>> eq = aa == ba
>> )
>>
>> println("&a:", aa, reflect.TypeOf(aa).String())
>> println("&b:", ba, reflect.TypeOf(ba).String())
>> println("&a == &b:", eq)
>> cmpIntPtr(aa, ba)
>> }
>>
>> func cmpIntPtr(p1 *int, p2 *int) {
>> fmt.Println("p1 == p2:", p1 == p2)
>> }
>>
>> &a: 0xc466f8 *int
>> &b: 0xc466f8 *int
>> &a == &b: falsep1 == p2: true
>>
>>
> Interestingly, the spec does not forbid that (or specifies it as
> implementation-defined), though the (implementation-defined)
> unsafe.Pointer rules  do, as using
> `unsafe.Pointer` to convert between pointers of different base types is
> only allowed if the target variable is at least as large as the source
> variable and both share an equivalent memory layout.
>
> I think the fact that the spec does not put any limits on the allowed
> behaviour of converting between `unsafe.Pointer` and other pointer types is
> a clear oversight that should be corrected (perhaps it should really be
> "The effect of converting between Pointer and uintptr is
> implementation-defined" should really say "and other types"). But I don't
> think it's a surprising fact that you can make a program behave in almost
> arbitrary ways by doing that.
>
>
>> I’m advocating for at least a FAQ article,
>>
>>
>> I tend to agree, though I'm not sure how to phrase that, beyond saying
>> "do not make any assumptions about the identity pointers to zero-sized
>> variables or with zero-sized base types or that where derived from one of
>> those" and I'm not sure how helpful that is.
>>
>>
>> It seems like a frequently asked question to me ;)
>>
>
> It is. But note that every time it is asked, it leads to considerable
> discussion, which seems to strongly suggest that it is hard to give a
> simple, unambiguous answer that people find satisfying.
>
> I think you should acknowledge that the spec *is* already trying to be
> very clear about this. The fact that you can poke holes in it is because
> writing a spec unambiguously is hard. But the two quoted phrases are there
> in the best attempt to clearly state that you can not rely on any
> assumptions about pointers to zero-sized variables - within the somewhat
> abstract framework of the spec. Feel free to propose a better one, I'm not
> actually arguing against that.
>
> And I'm also not arguing against an FAQ entry. Ideally, someone would
> suggest a phrasing that is sufficiently broad and unambiguous and clear to
> cover any version of this question people might ask, while also not
> contradicting the spec.
>
>
>> but also think the specification should be adapted, for clarity but also
>>> for the fact that only one pointer pointing to a zero-sized variable can
>>> compare differently to anything over time, even things having the same
>>> address value.
>>>
>>
>> Note that "address value" is not something that exists within the spec.
>> As for clarifying the spec here, maybe. I do think the behavior is covered,
>> as I outlined above. And as above, I'm not sure how to clarify it further,
>> while still leaving up the space we want to left open.
>>
>>
>> I vote for making this openness explicit, meaning that even the optimizer
>> is free to make assumptions that do not hold during runtime. So if you have
>> a pointer derived from something pointing to a zero-size type it can
>> compare with different results over time, even false when having the same
>> value. I do not believe that is what’s currently in the spec.
>>
>
>> Cheers
>> Oliver
>>
>>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAEkBMfGEJivxGLb6iEWMri0Szesf8EgVwR%2BV9CVCbv0rRvo15Q%40mail.gmail.com.


Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread Robert Engels
I would add that I think the Go team should strive to remove as much “implementation defined” or “undefined” from the spec as possible. Forgo the optimizations. It’s this language that makes C++ such a pain to work with especially in a cross platform manner. I think you can safely narrow the spec in this area without issue - since it would have been very difficult to use anyway. Maybe some highly specialized code that relied on a particular Go implementation might. On Jun 20, 2024, at 7:12 AM, 'Axel Wagner' via golang-nuts  wrote:On Thu, 20 Jun 2024 at 13:48, Oliver Eikemeier  wrote:Am 20.06.2024 um 13:24 schrieb Axel Wagner :We can see that 1. `unsafe.Pointer` is definitionally a pointer type, 2. in your example, the two `unsafe.Pointers` do not point to the same variable and do not have the value `nil` and 3. are not pointing at distinct zero-sized variables. So their comparison should be `false`, which is what your example observes.Does it (Go Playground)?func f5() {	var (		a  struct{}		b  int		aa = (*int)(unsafe.Pointer(&a))		ba = (*int)(unsafe.Pointer(&b))		eq = aa == ba	)	println("&a:", aa, reflect.TypeOf(aa).String())	println("&b:", ba, reflect.TypeOf(ba).String())	println("&a == &b:", eq)	cmpIntPtr(aa, ba)}func cmpIntPtr(p1 *int, p2 *int) {	fmt.Println("p1 == p2:", p1 == p2)}&a: 0xc466f8 *int
&b: 0xc466f8 *int
&a == &b: false
p1 == p2: trueInterestingly, the spec does not forbid that (or specifies it as implementation-defined), though the (implementation-defined) unsafe.Pointer rules
 do, as using `unsafe.Pointer` to convert between pointers of different 
base types is only allowed if the target variable is at least as large 
as the source variable and both share an equivalent memory layout.I
 think the fact that the spec does not put any limits on the allowed 
behaviour of converting between `unsafe.Pointer` and other pointer types
 is a clear oversight that should be corrected (perhaps it should really
 be "The effect of converting between Pointer and uintptr is 
implementation-defined" should really say "and other types"). But I 
don't think it's a surprising fact that you can make a program behave in almost arbitrary ways by doing that. I’m advocating for at least a FAQ article,I tend to agree, though I'm not sure how to phrase that, beyond saying "do not make any assumptions about the identity pointers to zero-sized variables or with zero-sized base types or that where derived from one of those" and I'm not sure how helpful that is.It seems like a frequently asked question to me ;)It is. But note that every time it is asked, it leads to considerable discussion, which seems to strongly suggest that it is hard to give a simple, unambiguous answer that people find satisfying.I think you should acknowledge that the spec *is* already trying to be very clear about this. The fact that you can poke holes in it is because writing a spec unambiguously is hard. But the two quoted phrases are there in the best attempt to clearly state that you can not rely on any assumptions about pointers to zero-sized variables - within the somewhat abstract framework of the spec. Feel free to propose a better one, I'm not actually arguing against that.And I'm also not arguing against an FAQ entry. Ideally, someone would suggest a phrasing that is sufficiently broad and unambiguous and clear to cover any version of this question people might ask, while also not contradicting the spec. but also think the specification should be adapted, for clarity but also for the fact that only one pointer pointing to a zero-sized variable can compare differently to anything over time, even things having the same address value.Note that "address value" is not something that exists within the spec. As for clarifying the spec here, maybe. I do think the behavior is covered, as I outlined above. And as above, I'm not sure how to clarify it further, while still leaving up the space we want to left open.I vote for making this openness explicit, meaning that even the optimizer is free to make assumptions that do not hold during runtime. So if you have a pointer derived from something pointing to a zero-size type it can compare with different results over time, even false when having the same value. I do not believe that is what’s currently in the spec. CheersOliver



-- 
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CAEkBMfGOWoQYrQ9qm_9%2BdyvEObJV3JP%2BhwwFj9%2Bgo%3DqusRVL7A%40mail.gmail.com.




-- 
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com.

Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread 'Axel Wagner' via golang-nuts
On Thu, 20 Jun 2024 at 13:48, Oliver Eikemeier 
wrote:

>
> Am 20.06.2024 um 13:24 schrieb Axel Wagner  >:
>
> We can see that 1. `unsafe.Pointer` is definitionally a pointer type, 2.
> in your example, the two `unsafe.Pointers` do not point to the same
> variable and do not have the value `nil` and 3. are not pointing at
> distinct zero-sized variables. So their comparison should be `false`, which
> is what your example observes.
>
>
> Does it (Go Playground )?
>
> func f5() {
> var (
> a  struct{}
> b  int
> aa = (*int)(unsafe.Pointer(&a))
> ba = (*int)(unsafe.Pointer(&b))
> eq = aa == ba
> )
>
> println("&a:", aa, reflect.TypeOf(aa).String())
> println("&b:", ba, reflect.TypeOf(ba).String())
> println("&a == &b:", eq)
> cmpIntPtr(aa, ba)
> }
>
> func cmpIntPtr(p1 *int, p2 *int) {
> fmt.Println("p1 == p2:", p1 == p2)
> }
>
> &a: 0xc466f8 *int
> &b: 0xc466f8 *int
> &a == &b: falsep1 == p2: true
>
>
Interestingly, the spec does not forbid that (or specifies it as
implementation-defined), though the (implementation-defined) unsafe.Pointer
rules  do, as using `unsafe.Pointer` to
convert between pointers of different base types is only allowed if the
target variable is at least as large as the source variable and both share
an equivalent memory layout.

I think the fact that the spec does not put any limits on the allowed
behaviour of converting between `unsafe.Pointer` and other pointer types is
a clear oversight that should be corrected (perhaps it should really be
"The effect of converting between Pointer and uintptr is
implementation-defined" should really say "and other types"). But I don't
think it's a surprising fact that you can make a program behave in almost
arbitrary ways by doing that.


> I’m advocating for at least a FAQ article,
>
>
> I tend to agree, though I'm not sure how to phrase that, beyond saying "do
> not make any assumptions about the identity pointers to zero-sized
> variables or with zero-sized base types or that where derived from one of
> those" and I'm not sure how helpful that is.
>
>
> It seems like a frequently asked question to me ;)
>

It is. But note that every time it is asked, it leads to considerable
discussion, which seems to strongly suggest that it is hard to give a
simple, unambiguous answer that people find satisfying.

I think you should acknowledge that the spec *is* already trying to be very
clear about this. The fact that you can poke holes in it is because writing
a spec unambiguously is hard. But the two quoted phrases are there in the
best attempt to clearly state that you can not rely on any assumptions
about pointers to zero-sized variables - within the somewhat abstract
framework of the spec. Feel free to propose a better one, I'm not actually
arguing against that.

And I'm also not arguing against an FAQ entry. Ideally, someone would
suggest a phrasing that is sufficiently broad and unambiguous and clear to
cover any version of this question people might ask, while also not
contradicting the spec.


> but also think the specification should be adapted, for clarity but also
>> for the fact that only one pointer pointing to a zero-sized variable can
>> compare differently to anything over time, even things having the same
>> address value.
>>
>
> Note that "address value" is not something that exists within the spec. As
> for clarifying the spec here, maybe. I do think the behavior is covered, as
> I outlined above. And as above, I'm not sure how to clarify it further,
> while still leaving up the space we want to left open.
>
>
> I vote for making this openness explicit, meaning that even the optimizer
> is free to make assumptions that do not hold during runtime. So if you have
> a pointer derived from something pointing to a zero-size type it can
> compare with different results over time, even false when having the same
> value. I do not believe that is what’s currently in the spec.
>

> Cheers
> Oliver
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAEkBMfGOWoQYrQ9qm_9%2BdyvEObJV3JP%2BhwwFj9%2Bgo%3DqusRVL7A%40mail.gmail.com.


Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread Oliver Eikemeier

> Am 20.06.2024 um 13:24 schrieb Axel Wagner :
> 
> We can see that 1. `unsafe.Pointer` is definitionally a pointer type, 2. in 
> your example, the two `unsafe.Pointers` do not point to the same variable and 
> do not have the value `nil` and 3. are not pointing at distinct zero-sized 
> variables. So their comparison should be `false`, which is what your example 
> observes.

Does it (Go Playground )?

func f5() {
var (
a  struct{}
b  int
aa = (*int)(unsafe.Pointer(&a))
ba = (*int)(unsafe.Pointer(&b))
eq = aa == ba
)

println("&a:", aa, reflect.TypeOf(aa).String())
println("&b:", ba, reflect.TypeOf(ba).String())
println("&a == &b:", eq)
cmpIntPtr(aa, ba)
}

func cmpIntPtr(p1 *int, p2 *int) {
fmt.Println("p1 == p2:", p1 == p2)
}

&a: 0xc466f8 *int
&b: 0xc466f8 *int
&a == &b: false
p1 == p2: true


> All of this would be fine. What makes your example confusing is that you use 
> `println` to output them and see that they "have the same value".

Not really. I use println to not let them escape (which would change results, 
obviously) and only print out the pointer values to show that we can construct 
some piece of code that sees them as identical, see above.

> Note that if you *don't* convert an `unsafe.Pointer` to `uintptr`, you have 
> no way to argue that they "are actually equal"

I can by doing something like

*aa = 42
fmt.Println(aa == ba, *ba)

“Two pointer values are equal if they point to the same variable” - aa and ba 
do. Note that “A variable is a storage location for holding a value.”

>> I’m advocating for at least a FAQ article,
> 
> I tend to agree, though I'm not sure how to phrase that, beyond saying "do 
> not make any assumptions about the identity pointers to zero-sized variables 
> or with zero-sized base types or that where derived from one of those" and 
> I'm not sure how helpful that is.

It seems like a frequently asked question to me ;)

>> but also think the specification should be adapted, for clarity but also for 
>> the fact that only one pointer pointing to a zero-sized variable can compare 
>> differently to anything over time, even things having the same address value.
> 
> Note that "address value" is not something that exists within the spec. As 
> for clarifying the spec here, maybe. I do think the behavior is covered, as I 
> outlined above. And as above, I'm not sure how to clarify it further, while 
> still leaving up the space we want to left open.

I vote for making this openness explicit, meaning that even the optimizer is 
free to make assumptions that do not hold during runtime. So if you have a 
pointer derived from something pointing to a zero-size type it can compare with 
different results over time, even false when having the same value. I do not 
believe that is what’s currently in the spec.

Cheers
Oliver

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/AEB06A98-1372-4478-BBEB-514B617852A2%40fillmore-labs.com.


Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread Jan Mercl
On Thu, Jun 20, 2024 at 1:26 PM 'Axel Wagner' via golang-nuts
 wrote:

> (apologies for the abundance of grammatical and spelling errors that occurred 
> during editing and of course only became visible after hitting "send")

(Send collapses the wave function  ;-)

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAA40n-VMr0y%3D842etNGux4Xubc6B3dkhHxxrWtpSocpJsGxBfg%40mail.gmail.com.


Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread 'Axel Wagner' via golang-nuts
(apologies for the abundance of grammatical and spelling errors that
occurred during editing and of course only became visible after hitting
"send")

On Thu, 20 Jun 2024 at 13:24, Axel Wagner 
wrote:

> On Thu, 20 Jun 2024 at 12:28, Oliver Eikemeier <
> eikeme...@fillmore-labs.com> wrote:
>
>> Let me start with this: I’m fine with the behavior, it is exotic enough
>> that even the optimizer should be allowed to assume something that doesn’t
>> hold during runtime, since it simplifies things.
>>
>> What I think is at least surprising and at worst lacking is the
>> documentation.
>>
>> It mentions “pointers” (plural) to zero-sized variables, but for this
>> behavior it is sufficient when only one pointer derives from a pointer to a
>> zero-sized variable, as demonstrated in the example below.
>>
>
> Re-visiting your example, it is indeed interesting that I realized before.
> I'll note that you need to involve `unsafe.Pointer` to observe this, as you
> may not compare pointers to different types. And `unsafe.Pointer`'s
> behaviors are somewhat left up to the implementation.
>
> The spec ays: 
>
> A Pointer is a pointer type  but a
>> Pointer value may not be dereferenced
>> . Any pointer or value of core
>> type  uintptr can be converted
>>  to a type of core type Pointer and
>> vice versa. The effect of converting between Pointer and uintptr is
>> implementation-defined.
>
>
> The thing that stands out is that it leaves the effect of converting to
> `uintptr` up to the implementation, but nothing else. So any other rule, as
> far as the language is concerned, should be derived from the rules for
> pointer types (except that they can not be dereferenced).
>
> One contradiction here is that this section references the definition of a
> pointer type, which says
>
> A pointer type denotes the set of all pointers to variables
>>  of a given type, called the *base
>> type* of the pointer.
>>
>
> This contradicts the nature of `unsafe.Pointer`, though, which does not
> have a base type. That difference is what causes the trouble: When the spec
> defines pointer comparisons by
>
> Pointer types are comparable. Two pointer values are equal if they point
>> to the same variable or if both have value nil. Pointers to distinct
>> zero-size 
>> variables may or may not be equal.
>
>
> We can see that 1. `unsafe.Pointer` is definitionally a pointer type, 2.
> in your example, the two `unsafe.Pointers` do not point to the same
> variable and do not have the value `nil` and 3. are not pointing at
> distinct zero-sized variables. So their comparison should be `false`, which
> is what your example observes.
>
> All of this would be fine. What makes your example confusing is that you
> use `println` to output them and see that they "have the same value". For
> that, we need to look at the definition of `println`
> :
>
> Current implementations provide several built-in functions useful during
>> bootstrapping. These functions are documented for completeness but are not
>> guaranteed to stay in the language. They do not return a result.
>>
>> Function   Behavior
>>
>> print  prints all arguments; formatting of arguments is 
>> implementation-specific
>> printlnlike print but prints spaces between arguments and a newline at 
>> the end
>>
>> Implementation restriction: print and println need not accept arbitrary
>> argument types, but printing of boolean, numeric, and string types
>>  must be supported.
>>
> Notably, this says nothing about what happens if you pass a pointer type.
> That is thus left up to the implementation. In effect, it does the same as
> `fmt.Println` ultimately: It converts the pointer to `uintptr`, which as
> we've seen above is left to the implementation.
>
> Note that if you *don't* convert an `unsafe.Pointer` to `uintptr`, you
> have no way to argue that they "are actually equal". And if you don't use
> `unsafe.Pointer` you have no way to compare pointers to variables of
> different types. So, the only way to observe that behavior is to enter what
> is implementation-defined.
>
> So, yes. Your example is interesting, but still within spec.
>
> I’m advocating for at least a FAQ article,
>>
>
> I tend to agree, though I'm not sure how to phrase that, beyond saying "do
> not make any assumptions about the identity pointers to zero-sized
> variables or with zero-sized base types or that where derived from one of
> those" and I'm not sure how helpful that is.
>
>
>> but also think the specification should be adapted, for clarity but also
>> for the fact that only one pointer pointing to a zero-sized variable can
>> compare differently to anything over t

Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread Jan Mercl
On Thu, Jun 20, 2024 at 1:16 PM Oliver Eikemeier
 wrote:

> • Pointer types are comparable. Two pointer values are equal if they point to 
> the same variable or if both have value nil. Pointers to distinct zero-size 
> variables may or may not be equal.

Compare to (made up) "NaNs always compare non-equal". It talks both
about '3.14 == NaN' and 'NaN == NaN'. The plural in our context means
"any, all and every". It does not specify only the last case of two
NaNs.

My 2c.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAA40n-W%3D9EX5BFgVWibHF1nz5xDgX3Z3v6ptyD%2BeSwJLeBtSEg%40mail.gmail.com.


Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread 'Axel Wagner' via golang-nuts
On Thu, 20 Jun 2024 at 12:28, Oliver Eikemeier 
wrote:

> Let me start with this: I’m fine with the behavior, it is exotic enough
> that even the optimizer should be allowed to assume something that doesn’t
> hold during runtime, since it simplifies things.
>
> What I think is at least surprising and at worst lacking is the
> documentation.
>
> It mentions “pointers” (plural) to zero-sized variables, but for this
> behavior it is sufficient when only one pointer derives from a pointer to a
> zero-sized variable, as demonstrated in the example below.
>

Re-visiting your example, it is indeed interesting that I realized before.
I'll note that you need to involve `unsafe.Pointer` to observe this, as you
may not compare pointers to different types. And `unsafe.Pointer`'s
behaviors are somewhat left up to the implementation.

The spec ays: 

A Pointer is a pointer type  but a
> Pointer value may not be dereferenced
> . Any pointer or value of core
> type  uintptr can be converted
>  to a type of core type Pointer and
> vice versa. The effect of converting between Pointer and uintptr is
> implementation-defined.


The thing that stands out is that it leaves the effect of converting to
`uintptr` up to the implementation, but nothing else. So any other rule, as
far as the language is concerned, should be derived from the rules for
pointer types (except that they can not be dereferenced).

One contradiction here is that this section references the definition of a
pointer type, which says

A pointer type denotes the set of all pointers to variables
>  of a given type, called the *base
> type* of the pointer.
>

This contradicts the nature of `unsafe.Pointer`, though, which does not
have a base type. That difference is what causes the trouble: When the spec
defines pointer comparisons by

Pointer types are comparable. Two pointer values are equal if they point to
> the same variable or if both have value nil. Pointers to distinct
> zero-size 
> variables may or may not be equal.


We can see that 1. `unsafe.Pointer` is definitionally a pointer type, 2. in
your example, the two `unsafe.Pointers` do not point to the same variable
and do not have the value `nil` and 3. are not pointing at distinct
zero-sized variables. So their comparison should be `false`, which is what
your example observes.

All of this would be fine. What makes your example confusing is that you
use `println` to output them and see that they "have the same value". For
that, we need to look at the definition of `println`
:

Current implementations provide several built-in functions useful during
> bootstrapping. These functions are documented for completeness but are not
> guaranteed to stay in the language. They do not return a result.
>
> Function   Behavior
>
> print  prints all arguments; formatting of arguments is 
> implementation-specific
> printlnlike print but prints spaces between arguments and a newline at 
> the end
>
> Implementation restriction: print and println need not accept arbitrary
> argument types, but printing of boolean, numeric, and string types
>  must be supported.
>
Notably, this says nothing about what happens if you pass a pointer type.
That is thus left up to the implementation. In effect, it does the same as
`fmt.Println` ultimately: It converts the pointer to `uintptr`, which as
we've seen above is left to the implementation.

Note that if you *don't* convert an `unsafe.Pointer` to `uintptr`, you have
no way to argue that they "are actually equal". And if you don't use
`unsafe.Pointer` you have no way to compare pointers to variables of
different types. So, the only way to observe that behavior is to enter what
is implementation-defined.

So, yes. Your example is interesting, but still within spec.

I’m advocating for at least a FAQ article,
>

I tend to agree, though I'm not sure how to phrase that, beyond saying "do
not make any assumptions about the identity pointers to zero-sized
variables or with zero-sized base types or that where derived from one of
those" and I'm not sure how helpful that is.


> but also think the specification should be adapted, for clarity but also
> for the fact that only one pointer pointing to a zero-sized variable can
> compare differently to anything over time, even things having the same
> address value.
>

Note that "address value" is not something that exists within the spec. As
for clarifying the spec here, maybe. I do think the behavior is covered, as
I outlined above. And as above, I'm not sure how to clarify it further,
while still leaving up the space we want to left open.


>
> I do not believe the specification is clear

Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread Oliver Eikemeier
https://go.dev/ref/spec#Comparison_operators

• Pointer types are comparable. Two pointer values are equal if they point 
to the same variable or if both have value nil. Pointers to distinct zero-size 
variables may or may not be equal.

Another example (Go Playground ):

func f4() {
var (
a  struct{}
b  int
aa = (*int)(unsafe.Pointer(&a))
ba = (*int)(unsafe.Pointer(&b))
eq = aa == ba
)

println("&a:", aa, reflect.TypeOf(aa).String())
println("&b:", ba, reflect.TypeOf(ba).String())
println("&a == &b:", eq)
}

&a: 0xc466f8 *int
&b: 0xc466f8 *int
&a == &b: false

We do not have “pointers to distinct zero-size variables”, only one pointer 
derived from a pointer to a zero-sized variable.

I don’t want to be stubborn. What would be the issue with at least adding a FAQ 
entry? I could open a PR suggesting something, although I’m not a native 
speaker and might not exactly hit the tone of the document.

> Am 20.06.2024 um 12:37 schrieb Jan Mercl <0xj...@gmail.com>:
> 
> On Thu, Jun 20, 2024 at 12:28 PM Oliver Eikemeier
>  wrote:
> 
>> It mentions “pointers” (plural) to zero-sized variables, but for this 
>> behavior it is sufficient when only one pointer derives from a pointer to a 
>> zero-sized variable, as demonstrated in the example below.
> 
> The plural is there because the specification discusses all such
> pointers, not a particular case.
> 
> The wording is IMO correct and clear. All/any pointers (plural) to
> zero sized objects may produce any/unpredictable result in comparison
> operations. Relying on the outcome is a bug, because the specs
> explicitly say otherwise.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/C02D6616-0B77-4F6F-8597-EFA355BF17E1%40fillmore-labs.com.


Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread Jan Mercl
On Thu, Jun 20, 2024 at 12:28 PM Oliver Eikemeier
 wrote:

> It mentions “pointers” (plural) to zero-sized variables, but for this 
> behavior it is sufficient when only one pointer derives from a pointer to a 
> zero-sized variable, as demonstrated in the example below.

The plural is there because the specification discusses all such
pointers, not a particular case.

The wording is IMO correct and clear. All/any pointers (plural) to
zero sized objects may produce any/unpredictable result in comparison
operations. Relying on the outcome is a bug, because the specs
explicitly say otherwise.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/CAA40n-W8sYn56qRwX9ijEe9eK5bBxKCf_M2tX4_pxPMrWgi2hQ%40mail.gmail.com.


Re: [go-nuts] Comparison of pointers to distinct zero-sized variables

2024-06-20 Thread Oliver Eikemeier
Let me start with this: I’m fine with the behavior, it is exotic enough that 
even the optimizer should be allowed to assume something that doesn’t hold 
during runtime, since it simplifies things.

What I think is at least surprising and at worst lacking is the documentation.

It mentions “pointers” (plural) to zero-sized variables, but for this behavior 
it is sufficient when only one pointer derives from a pointer to a zero-sized 
variable, as demonstrated in the example below.

I’m advocating for at least a FAQ article, but also think the specification 
should be adapted, for clarity but also for the fact that only one pointer 
pointing to a zero-sized variable can compare differently to anything over 
time, even things having the same address value.

I do not believe the specification is clear on this. Otherwise I don’t think 
this is urgent. But it seems to pop up repeatedly.

Cheers
Oliver

> Am 19.06.2024 um 23:16 schrieb 'Axel Wagner' via golang-nuts 
> :
> 
> The spec says both. It says
>> Two distinct zero-size variables may have the same address in memory.
> And it says
>> Pointers to distinct zero-size variables may or may not be equal.
> 
> The former means what you say. The latter means what Ian says.
> 
>> Then I have two pointers. Where in the spec is “the result of comparison of 
>> pointers may change over time”?
>>  
>> For example (Go Playground ):
>> 
>> func f3() {
>>  var (
>>  a  struct{}
>>  b  int
>>  aa = unsafe.Pointer(&a)
>>  ba = unsafe.Pointer(&b)
>>  eq = aa == ba
>>  )
>> 
>>  println("&a:", aa)
>>  println("&b:", ba)
>>  println("&a == &b:", eq)
>> }
>> 
>> gives
>> 
>> &a: 0xc46738
>> &b: 0xc46738
>> &a == &b: false 
>> 
>> and &b is not even a pointer to a zero-sized variable.

-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/golang-nuts/60900D25-852D-4A9F-904F-D2ECFF47576D%40fillmore-labs.com.