Bug 18315 - Setting color in System.Console produces garbage when trying to use a 256 color console and crashes on monochrome console
Summary: Setting color in System.Console produces garbage when trying to use a 256 col...
Status: RESOLVED FIXED
Alias: None
Product: Class Libraries
Classification: Mono
Component: System.Core ()
Version: 3.2.x
Hardware: PC Linux
: --- normal
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2014-03-12 06:52 UTC by delcypher
Modified: 2014-12-13 19:40 UTC (History)
4 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
ConsoleTest program (282 bytes, text/x-csharp)
2014-03-12 06:52 UTC, delcypher
Details
Output of infocmp when using xterm-256color on Arch Linux (2.78 KB, text/plain)
2014-03-12 13:31 UTC, delcypher
Details
Output of infocmp when using xtermm on Arch Linux (1.26 KB, text/plain)
2014-03-12 13:31 UTC, delcypher
Details
Strace output running ConsoleTest.exe for xterm-256color (34.66 KB, text/plain)
2014-03-12 15:01 UTC, delcypher
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on GitHub or Developer Community with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED FIXED

Description delcypher 2014-03-12 06:52:00 UTC
Created attachment 6288 [details]
ConsoleTest program

Description of Problem:
When using System.Console.BackgroundColor and System.Console.ForegroundColor to set colors. If the console is a 256 color console we print garbage (what look like escape characters) and when trying to use a monochrome console we crash!


Steps to reproduce the problem:
1. Build this simple test program (attached)
2. Run

$ TERM=xterm mono ConsoleTest.exe
$ TERM=xterm-256color mono ConsoleTest.exe
$ TERM=xtermm mono ConsoleTest.exe


Actual Results:
* Using TERM=xterm works and appears as expected producing
Hello World!

colored in the expected manner.

* Using TERM=xterm-256color produces garbage (looks like escape characters)

?%p1%{8}%<%t44%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;4%;m?%p1%{8}%<%t31%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;1%;mHello World!

* using TERM=xtermm (monochrome terminal) crashes the application

Unhandled Exception:
System.ArgumentNullException: Argument cannot be null.
Parameter name: format
  at System.String.FormatHelper (System.Text.StringBuilder result, IFormatProvider provider, System.String format, System.Object[] args) [0x00261] in /build/mono/src/mono-3.2.8/mcs/class/corlib/System/String.cs:2066 
  at System.String.Format (IFormatProvider provider, System.String format, System.Object[] args) [0x00000] in /build/mono/src/mono-3.2.8/mcs/class/corlib/System/String.cs:1960 
  at System.String.Format (System.String format, System.Object arg0) [0x00000] in /build/mono/src/mono-3.2.8/mcs/class/corlib/System/String.cs:1940 
  at System.TermInfoDriver.set_BackgroundColor (ConsoleColor value) [0x00027] in /build/mono/src/mono-3.2.8/mcs/class/corlib/System/TermInfoDriver.cs:447 
  at System.ConsoleDriver.set_BackgroundColor (ConsoleColor value) [0x0001f] in /build/mono/src/mono-3.2.8/mcs/class/corlib/System/ConsoleDriver.cs:86 
  at System.Console.set_BackgroundColor (ConsoleColor value) [0x00000] in /build/mono/src/mono-3.2.8/mcs/class/corlib/System/Console.cs:568 
  at ConsoleTest.MainClass.Main (System.String[] args) [0x00003] in /home/dsl11/test/ConsoleTest/ConsoleTest/Program.cs:9 
[ERROR] FATAL UNHANDLED EXCEPTION: System.ArgumentNullException: Argument cannot be null.
Parameter name: format
  at System.String.FormatHelper (System.Text.StringBuilder result, IFormatProvider provider, System.String format, System.Object[] args) [0x00261] in /build/mono/src/mono-3.2.8/mcs/class/corlib/System/String.cs:2066 
  at System.String.Format (IFormatProvider provider, System.String format, System.Object[] args) [0x00000] in /build/mono/src/mono-3.2.8/mcs/class/corlib/System/String.cs:1960 
  at System.String.Format (System.String format, System.Object arg0) [0x00000] in /build/mono/src/mono-3.2.8/mcs/class/corlib/System/String.cs:1940 
  at System.TermInfoDriver.set_BackgroundColor (ConsoleColor value) [0x00027] in /build/mono/src/mono-3.2.8/mcs/class/corlib/System/TermInfoDriver.cs:447 
  at System.ConsoleDriver.set_BackgroundColor (ConsoleColor value) [0x0001f] in /build/mono/src/mono-3.2.8/mcs/class/corlib/System/ConsoleDriver.cs:86 
  at System.Console.set_BackgroundColor (ConsoleColor value) [0x00000] in /build/mono/src/mono-3.2.8/mcs/class/corlib/System/Console.cs:568 
  at ConsoleTest.MainClass.Main (System.String[] args) [0x00003] in /home/dsl11/test/ConsoleTest/ConsoleTest/Program.cs:9 


Expected Results:

* Using TERM=xterm should produce correctly colored output. Which it does.

* Using TERM=xterm-256color should produce correctly colored output. It currently does not and garbage is printed.

* Using TERM=xtermm should not crash the application.


How often does this happen? 
Every time.

Additional Information:
$ mono --version
Mono JIT compiler version 3.2.8 (tarball Mon Mar  3 12:37:20 UTC 2014)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
	TLS:           __thread
	SIGSEGV:       altstack
	Notifications: epoll
	Architecture:  amd64
	Disabled:      none
	Misc:          softdebug 
	LLVM:          supported, not enabled.
	GC:            sgen


I'm using Arch Linux and I'm using konsole (KDE 4.12) as my terminal emulator.
Comment 1 Miguel de Icaza [MSFT] 2014-03-12 12:43:22 UTC
This looks like a problem with the terminfo database on Arch Linux.

Unable to reproduce on Mac.

Please provide the output of "infocmp" when running with the various TERM settings.

In particular the settings for setab and setaf, this is what OSX shows for the xterm-color256:

	setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
	setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,
Comment 2 delcypher 2014-03-12 13:31:24 UTC
Created attachment 6292 [details]
Output of infocmp when using xterm-256color on Arch Linux
Comment 3 delcypher 2014-03-12 13:31:53 UTC
Created attachment 6293 [details]
Output of infocmp when using xtermm on Arch Linux
Comment 4 delcypher 2014-03-12 13:53:09 UTC
Thanks for replying. I've attached that output of using infocmp on my system when using xterm-256color and xtermm.

For the particular settings you were interested in

xterm-color256:

setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,

This looks identical to what you posted earlier for OSX.

xtermm:

setab and setaf do not exist.

I'm not actually sure how the escape codes are used (I normally just do something like "$ tput setaf 2") where does the color number go when you use the setab or setaf sequence?

The output I see running ConsoleTest.exe when using xterm-color-256, is that significant?

?%p1%{8}%<%t44%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;4%;m?%p1%{8}%<%t31%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;1%;mHello World!

The beginning looks a little bit like setab, followed by something similar to setaf.

Any ideas?
Comment 5 Miguel de Icaza [MSFT] 2014-03-12 14:27:18 UTC
The 256 setup is an issue with something not processing the ESC character, or some other garbage perhaps being in the output.   You might want to strace the Mono process and log all the output going to the standard output so we can identify the cause.

Or you might have a broken terminal emulator to begin with.   Which terminal app is this?

Puzzled about the other one.    You should instrument this file:

/build/mono/src/mono-3.2.8/mcs/class/corlib/System/TermInfoDriver.cs:447

And log what the actual value of the variable being written is.
Comment 6 delcypher 2014-03-12 14:54:47 UTC
Okay I did (this for TERM=xterm-256color)

$ strace ./ConsoleTest.exe 2> xterm-256color.strace.txt 1> xterm-256color.stdout.txt

The xterm-256color.stdout.txt file contained ONLY "Hello World!" and no escape sequences were in there (is that normal?)

I will attach the xterm-256color.strace.txt.

For your information the terminal program I am using Konsole 2.12.3, I just tried it on xterm (303-1) and I get the same issue.

For the other issue (the crash) by "instrument" do you mean I should?

1. Download the source used by my distro
2. Modify /build/mono/src/mono-3.2.8/mcs/class/corlib/System/TermInfoDriver.cs:447

to log something ( https://github.com/mono/mono/blob/mono-3.2.8-branch/mcs/class/corlib/System/TermInfoDriver.cs#L447 ). Looking at the source I take it you want me to record the value of the string setlbgcolor? I take it I should write it to a file rather than printing it to stdout?

3. Rebuild mono and install
4. Rerun my ConsoleTest.exe program.
Comment 7 delcypher 2014-03-12 15:01:55 UTC
Created attachment 6296 [details]
Strace output running ConsoleTest.exe for xterm-256color

Note this was executed using

$ strace ./ConsoleTest.exe 2> xterm-256color.strace.txt

and NOT

$ strace ./ConsoleTest.exe 2> xterm-256color.strace.txt 1> xterm-256color.stdout.txt

It seems that if I send stdout to a file I no longer see any write() system call in the strace output for the escape characters.
Comment 8 Gergely Buday 2014-10-09 08:31:21 UTC
I had this problem using Pash, a PowerShell implemenation in Mono.

https://github.com/Pash-Project/Pash

How could I contribute solving this problem?
Comment 9 delcypher 2014-10-09 10:04:44 UTC
IIRC when I last looked at this I realised the implementation in ``mcs/class/corlib/System/TermInfoDriver.cs`` was wrong.

If you read [1] the "Parameterized Strings" section you'll see that actually that things like ``setab`` and ``setaf`` can actually be parametrised.

For default terminal you get something like...

$ TERM=xterm infocmp | grep -E 'set.[b|f]'
	setab=\E[4%p1%dm, setaf=\E[3%p1%dm,

But for the 256 color terminal you get this.

$ TERM=xterm-256color infocmp | grep -E 'set.[b|f]'
	setab=\E[%?%p1%{8}%<%t4%p1%d%e%p1%{16}%<%t10%p1%{8}%-%d%e48;5;%p1%d%;m,
	setaf=\E[%?%p1%{8}%<%t3%p1%d%e%p1%{16}%<%t9%p1%{8}%-%d%e38;5;%p1%d%;m,

To support the terminal properly the string needs to be evaluated. You can see that the for the 256 color terminal there are things like if-then-else and comparison operations insides the string! The current implementation in ``mcs/class/corlib/System/TermInfoDriver.cs`` assumes that there aren't operations like that inside setab and setaf.

I wish I had the time to fix this but I really don't right now.

If you fell like fixing this, that would be great.

[1] (man 5 terminfo) or https://www.mkssoftware.com/docs/man5/terminfo.5.asp
Comment 10 Miguel de Icaza [MSFT] 2014-12-13 19:40:13 UTC
The parameterized renderer has been implemented, by taking this from .NET's Core implementation.

Fixed on mono/master fda6bf1a3353906cefb484dd60d817c90beedb06