Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 15 Jul 2013 18:35:59 +0300
From:      Andriy Gapon <avg@FreeBSD.org>
To:        gahr@FreeBSD.org
Cc:        tcltk@FreeBSD.org
Subject:   Re: weird problem with git gui
Message-ID:  <51E416DF.6040903@FreeBSD.org>
In-Reply-To: <20130715083241.GB21355@gahrfit.gahr.ch>
References:  <51E3AD58.6030001@FreeBSD.org> <20130715083241.GB21355@gahrfit.gahr.ch>

next in thread | previous in thread | raw e-mail | index | archive | help
on 15/07/2013 11:32 Pietro Cerutti said the following:
> On 2013-Jul-15, 11:05, Andriy Gapon wrote:
>>
>> I started having some weird problems with "git gui" command after a recent
>> massive upgrade of ports (the last one was > 3 months ago), which also included
>> updates of tcl and tk.
>>
>> Here is a small snippet from modified tcl/tk code in
>> /usr/local/libexec/git-core/git-gui:
>>
>> catch {puts "1GIT_DIR is $env(GIT_DIR)"} # added by me
>> menu .mbar -tearoff 0
>> catch {puts "2GIT_DIR is $env(GIT_DIR)"} # added by me
>>
>> I think the following output speaks for itself:
>> 1GIT_DIR is .git
>> 2GIT_DIR as .git.git
>>
>> I am very puzzled as to why the 'menu' command would cause such a detrimental
>> change to the environment.
>> I am trying to debug this issue right now.  I see that there is a call to
>> TclSetupEnv() (from generic/tclEnv.c) when 'menu' is executed.
>>
>> Any hints and suggestions are very appreciated!
>> I'll get back with any additional details I discover.
> 
> I fear I can't reproduce it locally, 
> 
> puts [info patchlevel]
> puts "1 - $env(GIT_DIR)"
> menu .mbar -tearoff 0
> puts "2 - $env(GIT_DIR)"
> 
> gives
> 
> 8.6.0
> 1 - .git
> 2 - .git
> 
> I get to it by opening an existing repository. Could you please
> elaborate on the steps you take to get to that point?

I just ran git gui in an existing repository as well.  Also, I could not
reproduce the problem on another machine that I have access too.  Weird...

I do not have any conclusions or solution, but i have some further observations.
It seems that in my environment tcl wants to manipulate 'environ' global
variable directly instead of using putenv/setenv/tec.  I am not sure why this is
preferred, but unix/tclUnixPort.h defines USE_PUTENV only for __CYGWIN__ or APPLE.

Then I decided to use gdb to see how 'environ' is manipulated.
$ gdb76 /usr/local/bin/wish8.6
(gdb) set args /usr/local/libexec/git-core/git-gui --
(gdb) watch environ
(gdb) run

I noticed that first tcl changes environ here:
(gdb) bt
#0  TclSetEnv (name=<optimized out>, value=0x8044fd010
"/usr/local/libexec/git-core/git-gui--askpass")
    at /usr/obj/ports/usr/ports/lang/tcl86/work/tcl8.6.0/generic/tclEnv.c:205
#1  0x0000000800c09254 in EnvTraceProc (clientData=<optimized out>,
interp=0x804039010, name1=0x80419ad90 "env", name2=0x804474b30 "SSH_ASKPASS",
    flags=32) at
/usr/obj/ports/usr/ports/lang/tcl86/work/tcl8.6.0/generic/tclEnv.c:593
#2  0x0000000800c5efe4 in TclCallVarTraces (iPtr=0x804039010,
arrayPtr=0x804098c90, varPtr=0x804486d90, part1=0x80419ad90 "env",
    part2=0x804474b30 "SSH_ASKPASS", flags=32, leaveErrMsg=512) at
/usr/obj/ports/usr/ports/lang/tcl86/work/tcl8.6.0/generic/tclTrace.c:2627
#3  0x0000000800c5f396 in TclObjCallVarTraces (iPtr=0x804039010,
arrayPtr=0x804098c90, varPtr=0x804486d90, part1Ptr=<optimized out>,
    part2Ptr=0x80448bc40, flags=32, leaveErrMsg=512, index=-1) at
/usr/obj/ports/usr/ports/lang/tcl86/work/tcl8.6.0/generic/tclTrace.c:2513
#4  0x0000000800c66373 in TclPtrSetVar (interp=0x804039010, varPtr=0x804486d90,
arrayPtr=0x804098c90, part1Ptr=0x80422ac80, part2Ptr=0x80448bc40,
    newValuePtr=0x80448b850, flags=512, index=-1) at
/usr/obj/ports/usr/ports/lang/tcl86/work/tcl8.6.0/generic/tclVar.c:1963
#5  0x0000000800c0ffff in TEBCresume (data=<optimized out>, interp=0x804039010,
result=0)
    at /usr/obj/ports/usr/ports/lang/tcl86/work/tcl8.6.0/generic/tclExecute.c:3357
#6  0x0000000800bad81c in TclNRRunCallbacks (interp=0x804039010, result=0,
rootPtr=0x0)
    at /usr/obj/ports/usr/ports/lang/tcl86/work/tcl8.6.0/generic/tclBasic.c:4350
#7  0x0000000800bad8d5 in Tcl_EvalObjv (interp=0x804039010, objc=<optimized
out>, objv=<optimized out>, flags=<optimized out>)
    at /usr/obj/ports/usr/ports/lang/tcl86/work/tcl8.6.0/generic/tclBasic.c:4142
#8  0x0000000800bae9a9 in TclEvalEx (interp=<optimized out>, script=<optimized
out>, numBytes=73811, flags=<optimized out>, line=1227,
    clNextOuter=<optimized out>,
    outerScript=0x804450010 "#!/bin/sh\n# Tcl ignores the next line -*- tcl -*-
\\\n if test \"z$*\" = zversion \\\n || test \"z$*\" = z--version; \\\n then
\\\n\techo 'git-gui version 0.16.0.15.gf6dd78'; \\\n\texit; \\\n fi; \\\n
argv0=$0; \\\n exec '"...)
    at /usr/obj/ports/usr/ports/lang/tcl86/work/tcl8.6.0/generic/tclBasic.c:5248
#9  0x0000000800c36297 in Tcl_FSEvalFileEx (interp=0x804039010,
pathPtr=0x804074030, encodingName=<optimized out>)
    at /usr/obj/ports/usr/ports/lang/tcl86/work/tcl8.6.0/generic/tclIOUtil.c:1812
#10 0x0000000800872d5c in Tk_MainEx () from /usr/local/lib/libtk86.so
#11 0x000000000040088f in main ()

(Please note that line numbers are slightly skewed, because of some debugging
printfs)

And then environ is modified here again:
(gdb) bt
#0  0x00000008026b0845 in ?? () from /lib/libc.so.7
#1  0x00000008026afe8b in ?? () from /lib/libc.so.7
#2  0x00000008026afd8b in setenv () from /lib/libc.so.7
#3  0x0000000801669d2c in FT_Load_Glyph () from /usr/local/lib/libfreetype.so.9
#4  0x00000008011108f4 in XftFontLoadGlyphs () from /usr/local/lib/libXft.so.2
#5  0x000000080110e309 in XftGlyphExtents () from /usr/local/lib/libXft.so.2
#6  0x000000080110e572 in XftTextExtents32 () from /usr/local/lib/libXft.so.2
#7  0x000000080090fdea in Tk_MeasureChars () from /usr/local/lib/libtk86.so
#8  0x000000080091010f in InitFont () from /usr/local/lib/libtk86.so
#9  0x0000000800910251 in TkpGetFontFromAttributes () from /usr/local/lib/libtk86.so
#10 0x00000008008696ac in Tk_AllocFontFromObj () from /usr/local/lib/libtk86.so
#11 0x00000008008607f3 in DoObjConfig () from /usr/local/lib/libtk86.so
#12 0x00000008008610da in Tk_InitOptions () from /usr/local/lib/libtk86.so
#13 0x00000008008937b2 in MenuCmd () from /usr/local/lib/libtk86.so
#14 0x0000000800bad36d in TclNREvalObjv (interp=0x804039010, objc=4,
objv=0x80407e2f0, flags=<optimized out>, cmdPtr=0x804155c10)
    at /usr/obj/ports/usr/ports/lang/tcl86/work/tcl8.6.0/generic/tclBasic.c:4308
#15 0x0000000800bad8c8 in Tcl_EvalObjv (interp=0x804039010, objc=<optimized
out>, objv=<optimized out>, flags=<optimized out>)
    at /usr/obj/ports/usr/ports/lang/tcl86/work/tcl8.6.0/generic/tclBasic.c:4141
#16 0x0000000800bae9a9 in TclEvalEx (interp=<optimized out>, script=<optimized
out>, numBytes=39162, flags=<optimized out>, line=2646,
    clNextOuter=<optimized out>,
    outerScript=0x804450010 "#!/bin/sh\n# Tcl ignores the next line -*- tcl -*-
\\\n if test \"z$*\" = zversion \\\n || test \"z$*\" = z--version; \\\n then
\\\n\techo 'git-gui version 0.16.0.15.gf6dd78'; \\\n\texit; \\\n fi; \\\n
argv0=$0; \\\n exec '"...)
    at /usr/obj/ports/usr/ports/lang/tcl86/work/tcl8.6.0/generic/tclBasic.c:5248
#17 0x0000000800c36297 in Tcl_FSEvalFileEx (interp=0x804039010,
pathPtr=0x804074030, encodingName=<optimized out>)
    at /usr/obj/ports/usr/ports/lang/tcl86/work/tcl8.6.0/generic/tclIOUtil.c:1812
#18 0x0000000800872d5c in Tk_MainEx () from /usr/local/lib/libtk86.so
#19 0x000000000040088f in main ()

After this modification of environ things go very sour for tcl.

... and now I also know why I have this problem on this particular machine!
I have a patched version of libfreetype (print/freetype2 with custom
'infinality' patch).  So apparently the unmodified version does not call setenv
and so tcl has full control.  On the other hand with my version setenv confuses tcl.

I think that in general we should allow setenv to be called from beyond tcl
control even while under tcl interpreter.  So I consider this to be an exotic
bug in tcl.  Not sure how to proceed from here though.

-- 
Andriy Gapon



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?51E416DF.6040903>