MichaelChirico / r-bugs

A ⚠️read-only⚠️mirror of https://bugs.r-project.org/
20 stars 0 forks source link

[BUGZILLA #17569] Infinite loop with pie using UTF-8 labels #6743

Closed MichaelChirico closed 4 years ago

MichaelChirico commented 4 years ago

Hi, I've just noticed that calling pie() on a table whose name contains UTF-8 characters seems to make pie() enter in a infinite loop.

Just try the following code:

tbl <- c( 1, 2, 3, 4 5) names( tbl ) <- c( "OK", "Correct", "With é", "OK" ) pie( tbl )

The display stops when trying to display the third label. It works perfectly when removing the é, and there is no problem when using barplot()

The bug is still present in R 3.6.0 (but this version is not proposed in the version selector above...)

Tried on linux/Mageia, with a fresh installed R 3.6.0 and no other package loaded...


METADATA

MichaelChirico commented 4 years ago

Oups, tbl <- 1:4 and not 1:5, sorry


METADATA

MichaelChirico commented 4 years ago

tbl <- 1:4 names( tbl ) <- c( "OK", "Correct", "With é", "OK" ) pie( tbl )

works fine on my Debian Linux system.

-k


METADATA

MichaelChirico commented 4 years ago

(In reply to Kurt Hornik from comment #2)

tbl <- 1:4
names( tbl ) <- c( "OK", "Correct", "With é", "OK" )
pie( tbl )

works fine on my Debian Linux system.

-k

Makes things difficult to identify... I am ready to give any needed information on the system/libraries that could be needed to identify the problem.

For instance :

sessionInfo()

R version 3.6.0 (2019-04-26) Platform: x86_64-pc-linux-gnu (64-bit) Running under: Mageia 6

Matrix products: default BLAS: /usr/local/lib64/R/lib/libRblas.so LAPACK: /usr/local/lib64/R/lib/libRlapack.so

locale: [1] LC_CTYPE=fr_FR.UTF-8 LC_NUMERIC=C
[3] LC_TIME=fr_FR.UTF-8 LC_COLLATE=fr_FR.UTF-8
[5] LC_MONETARY=fr_FR.UTF-8 LC_MESSAGES=fr_FR.UTF-8
[7] LC_PAPER=fr_FR.UTF-8 LC_NAME=C
[9] LC_ADDRESS=C LC_TELEPHONE=C
[11] LC_MEASUREMENT=fr_FR.UTF-8 LC_IDENTIFICATION=C

attached base packages: [1] stats graphics grDevices utils datasets methods base

loaded via a namespace (and not attached): [1] compiler_3.6.0

$ uname -a Linux [...) 4.18.20-server-1.mga6 #1 SMP Sun Nov 25 18:16:20 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

$ xdpyinfo name of display: :0.0 version number: 11.0 vendor string: Mageia vendor release number: 11905000 maximum request size: 16777212 bytes


METADATA

MichaelChirico commented 4 years ago

In one line, this is

 pie(c(OK = 1, Correct = 2, "With é" = 3, "OK, too" = 4))

and that works nicely (and does nicely "plot" the 'é' as well), also for me (and most probably almost all R users ..)

sessionInfo()

R version 3.6.0 (2019-04-26) Platform: x86_64-pc-linux-gnu (64-bit) Running under: Fedora 28 (Twenty Eight)

Matrix products: default BLAS: /...../R-3.6.0-inst/lib/libRblas.so LAPACK: /...../R-3.6.0-inst/lib/libRlapack.so

locale: [1] LC_CTYPE=de_CH.UTF-8 LC_NUMERIC=C LC_TIME=en_US.UTF-8
[4] LC_COLLATE=de_CH.UTF-8 LC_MONETARY=en_US.UTF-8 LC_MESSAGES=de_CH.UTF-8
[7] LC_PAPER=de_CH.UTF-8 LC_NAME=C LC_ADDRESS=C
[10] LC_TELEPHONE=C LC_MEASUREMENT=de_CH.UTF-8 LC_IDENTIFICATION=C

attached base packages: [1] graphics grDevices datasets stats utils methods base

other attached packages: [1] fortunes_1.5-4 sfsmisc_1.1-4

loaded via a namespace (and not attached): [1] compiler_3.6.0 tools_3.6.0

capabilities()
   jpeg         png        tiff       tcltk         X11        aqua    http/ftp 
   TRUE        TRUE        TRUE        TRUE        TRUE       FALSE        TRUE 
sockets      libxml        fifo      cledit       iconv         NLS     profmem 
   TRUE        TRUE        TRUE       FALSE        TRUE        TRUE       FALSE 
  cairo         ICU long.double     libcurl 
   TRUE        TRUE        TRUE        TRUE 
pie( c(OK = 1, Correct = 2, "With é" = 3, "OK, too" = 4))
.Device

[1] "X11cairo"

--------

(In reply to Emmanuel CURIS from comment #0)
The bug is still present in R 3.6.0 (but this version is not proposed in the
version selector above...)

But the version 3.6.x is proposed ... I had decided we would not want so extremely many versions...


METADATA

MichaelChirico commented 4 years ago

As you are on a Linux, can you please run R as

R -d gdb --vanilla

and then press 'r' (= 'run') to start R, then at the prompt do the

pie(c(OK = 1, Correct = 2, "With �" = 3, "OK, too" = 4))

and when it "loops" you should be able to interrupt (only when inside debugger) and then type 'bt' to see the back trace etc


METADATA

MichaelChirico commented 4 years ago

(In reply to Martin Maechler from comment #4 and #5) Sorry for missing the 3.6.x, I relied on the alphabetical order so didn't tried to go upward in the list, I missed the change from R 3.5.0 to 3.6.x without R :(

Results from R functions:

capabilities()
   jpeg         png        tiff       tcltk         X11        aqua 
   TRUE        TRUE        TRUE        TRUE        TRUE       FALSE 

http/ftp sockets libxml fifo cledit iconv TRUE TRUE TRUE TRUE TRUE TRUE NLS profmem cairo ICU long.double libcurl TRUE FALSE TRUE TRUE TRUE TRUE

.Device

[1] "null device"

pie(c(OK = 1, Correct = 2, "With é" = 3, "OK, too" = 4))

^C

.Device

[1] "X11"

May be the difference is between cairo and native X11 ?

Results from the call from gdb

pie(c(OK = 1, Correct = 2, "With é" = 3, "OK, too" = 4))

^C Program received signal SIGINT, Interrupt. 0x0000000000511077 in CONS_NR (car=0x842ef8, cdr=cdr@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x841010) at memory.c:2411 2411 QUICK_GET_FREE_NODE(s);

(gdb) bt

0 0x0000000000511077 in CONS_NR (car=0x842ef8, cdr=cdr@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x841010)

at memory.c:2411

1 0x00000000004ccf39 in bcEval (body=body@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x179d148,

rho=rho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x32c27b8, useCache=useCache@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=TRUE) at eval.c:6837

2 0x00000000004d9dc0 in Rf_eval (e=0x179d148, rho=rho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x32c27b8)

at eval.c:620

3 0x00000000004db738 in R_execClosure (call=call@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x32c28d0,

newrho=newrho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x32c27b8, sysparent=<optimized out>, 
rho=rho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x873680, arglist=arglist@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x32c2828, 
op=op@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x179d1b8) at eval.c:1780

4 0x00000000004dc3d4 in Rf_applyClosure (call=call@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x32c28d0,

op=op@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x179d1b8, arglist=<optimized out>, rho=rho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x873680, 
suppliedvars=<optimized out>) at eval.c:1706

5 0x00000000004d9d72 in Rf_eval (e=0x32c28d0, rho=0x873680) at eval.c:743

6 0x00000000004b7a1f in R_FindNamespace (info=info@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x32b2c50)

at envir.c:3618

7 0x00007ffff248e2a8 in translateFontFamily (xd=0x2860f10,

family=<optimized out>) at devX11.c:1778

8 SetFont (gc=0x7fffffff98a0, xd=xd@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2860f10) at devX11.c:1107

9 0x00007ffff248e743 in X11_MetricInfo (c=65533, gc=,

ascent=0x7fffffff9810, descent=0x7fffffff9818, width=0x7fffffff9820, 
dd=<optimized out>) at devX11.c:1836

10 0x00000000004aaf22 in GEText (x=, y=,

str=str@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x14aa4d8 "With �", enc=CE_UTF8, xc=xc@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=1, 
yc=<optimized out>, yc@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=nan(0x0000007a2), rot=rot@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0, 
gc=gc@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x7fffffff98a0, dd=dd@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x288b190) at engine.c:1804

11 0x00007ffff2bf1f50 in Rf_GText (x=166.62628159495273,

y=250.30229443143043, coords=coords@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=13, 
str=str@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x14aa4d8 "With �", enc=CE_UTF8, xc=xc@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=1, 
yc=yc@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=nan(0x0000007a2), rot=rot@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0, dd=dd@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x288b190)
at graphics.c:3023

12 0x00007ffff2c0b993 in C_text (args=) at plot.c:2239

13 0x0000000000497bc3 in do_External (call=call@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2945198,

op=op@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x85e308, args=args@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2973ff8, env=env@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2974a78)
at dotcode.c:548

14 0x0000000000499dfe in do_Externalgr (call=0x2945198, op=0x85e308,

args=0x2973ff8, env=0x2974a78) at dotcode.c:1318

15 0x00000000004d43aa in bcEval (body=body@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x293e160,

rho=rho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2974a78, useCache=useCache@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=TRUE) at eval.c:6722

16 0x00000000004d9dc0 in Rf_eval (e=0x293e160, rho=rho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2974a78)

at eval.c:620

17 0x00000000004db738 in R_execClosure (call=call@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2970f20,

newrho=newrho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2974a78, sysparent=<optimized out>, 
rho=rho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2971268, arglist=arglist@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2971578, 
op=op@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x293e898) at eval.c:1780

18 0x00000000004dc3d4 in Rf_applyClosure (call=0x2970f20, op=0x293e898,

arglist=<optimized out>, rho=0x2971268, suppliedvars=<optimized out>)
at eval.c:1706

19 0x0000000000515b16 in applyMethod (call=call@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2970f20,

op=op@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x293e898, args=<optimized out>, rho=rho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2971268, 
newvars=newvars@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x29710a8) at objects.c:118

20 0x000000000051685d in dispatchMethod (op=op@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x11abe00,

sxp=0x293e898, dotClass=0x841010, cptr=cptr@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x7fffffffbbb0, 
method=method@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x12c5ec0, generic=generic@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x9ad518 "text", 
rho=0x2971268, callrho=0x27ee040, defrho=0x13e4138) at objects.c:436

21 0x0000000000516cea in Rf_usemethod (generic=0x9ad518 "text",

obj=obj@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x296b9d8, call=call@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x11ac228, 
args=args@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x841010, rho=rho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2971268, 
callrho=callrho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x27ee040, defrho=0x13e4138, ans=0x7fffffffad18)
at objects.c:486

22 0x0000000000516ff1 in do_usemethod (call=0x11ac228, op=,

args=<optimized out>, env=0x2971268) at objects.c:565

23 0x00000000004cc6d4 in bcEval (body=body@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x11ac1f0,

rho=rho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2971268, useCache=useCache@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=TRUE) at eval.c:6785

24 0x00000000004d9dc0 in Rf_eval (e=0x11ac1f0, rho=rho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2971268)

at eval.c:620

25 0x00000000004db738 in R_execClosure (call=call@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x27ec120,

newrho=newrho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2971268, sysparent=<optimized out>, 
rho=rho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x27ee040, arglist=arglist@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2971578, 
op=op@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x11abe00) at eval.c:1780

26 0x00000000004dc3d4 in Rf_applyClosure (call=call@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x27ec120,

op=op@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x11abe00, arglist=<optimized out>, rho=rho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x27ee040, 
suppliedvars=<optimized out>) at eval.c:1706

27 0x00000000004d4925 in bcEval (body=body@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x27e43b8,

rho=rho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x27ee040, useCache=useCache@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=TRUE) at eval.c:6733

28 0x00000000004d9dc0 in Rf_eval (e=0x27e43b8, rho=rho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x27ee040)

at eval.c:620

29 0x00000000004db738 in R_execClosure (call=call@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2706b00,

newrho=newrho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x27ee040, sysparent=<optimized out>, 
rho=rho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x873680, arglist=arglist@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x27ee350, 
op=op@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2706898) at eval.c:1780

30 0x00000000004dc3d4 in Rf_applyClosure (call=call@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2706b00,

op=op@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2706898, arglist=<optimized out>, rho=rho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x873680, 
suppliedvars=<optimized out>) at eval.c:1706

31 0x00000000004d9d72 in Rf_eval (e=e@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2706b00, rho=rho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x873680)

at eval.c:743

32 0x00000000005078e9 in Rf_ReplIteration (rho=0x873680,

savestack=<optimized out>, browselevel=0, state=0x7fffffffcc70)
at main.c:260

33 0x0000000000507c38 in R_ReplConsole (rho=0x873680, savestack=0,

browselevel=0) at main.c:310

34 0x0000000000507cc5 in run_Rmainloop () at main.c:1086

35 0x0000000000507d22 in Rf_mainloop () at main.c:1093

36 0x000000000041b018 in main (ac=, av=)

at Rmain.c:29

(gdb) cont Continuing. ^C Program received signal SIGINT, Interrupt. R_Newhashpjw (s=s@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x7ffff24989b9 ".X11env") at envir.c:222 222 for (p = (char ) s; p; p++) { & (gdb) cont Continuing. ^C Program received signal SIGINT, Interrupt. 0x00000000004cb4f6 in bcEval (body=body@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x179d148, rho=rho@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=0x2b2dfd8, useCache=useCache@<::CENSORED -- SEE ORIGINAL ON BUGZILLA::>=TRUE) at eval.c:6517 6517 OP(GETVAR, 1): DO_GETVAR(FALSE, FALSE);


METADATA

MichaelChirico commented 4 years ago

Indeed, your .Device |--> "X11" has been the clue.

Now I can replicate:

X11(type = "Xlib") .Device # now shows "X11" pie(c(OK = 1, Correct = 2, "With é" = 3, "OK, too" = 4)) # --> hangs !!

-- and your backtrace is revealing too: I think it "shows" that the font metrics somehow can't be found for the non-ASCII character there ...


METADATA

MichaelChirico commented 4 years ago

(In reply to Martin Maechler from comment #7)

Indeed, your .Device |--> "X11"   has been the clue.

Now I *can* replicate:

X11(type = "Xlib")
.Device # now shows "X11"
pie(c(OK = 1, Correct = 2, "With é" = 3, "OK, too" = 4)) # --> hangs !!

-- and your backtrace is revealing too:  I think it "shows" that the font
metrics somehow can't be found for the non-ASCII character there ...

Great (in some sens at least). What is quite strange is that I never experienced such a thing with other graphical functions in R, despite a large use of UTF-8 characters in my scripts. But I didn't managed to understand what pie() does differently than the others...


METADATA

MichaelChirico commented 4 years ago

(In reply to Emmanuel CURIS from comment #8)

What is quite strange is that I never experienced such a thing with other
graphical functions in R, despite a large use of UTF-8 characters in my
scripts.  But I didn't managed to understand what pie() does differently
than the others...

Well, it just calls text().

I also get the infinite loop

X11(type = "Xlib") plot(1,1) ; text(1,1, "with ä")

Interestingly, it seems to only happen when calling text() directly, but not e.g. here :

plot(1,1, xlab = "with é", main = "Voilà")

and here

mtext(side=3, "¡ Voilà, Martin Mächler in Zürich !")

but indeed "hangs" with text()

So the font problem only happens when going via text() but not when going via title() {which is used for the above 'xlab = , main = ') or via mtext().

Indeed, these R functions each call into different C code, C_text(), vs C_title() vs C_mtext()
and it seems C_text() does something not as well as the other two. All three function's source code is in /src/library/graphics/src/plot.c

Maybe Paul can have a look?


METADATA

MichaelChirico commented 4 years ago

(In reply to Martin Maechler from comment #9)

(In reply to Emmanuel CURIS from comment #8)
> What is quite strange is that I never experienced such a thing with other
> graphical functions in R, despite a large use of UTF-8 characters in my
> scripts.  But I didn't managed to understand what pie() does differently
> than the others...

Well, it just calls  text().

I also get the infinite loop

X11(type = "Xlib")
plot(1,1) ; text(1,1, "with ä")

Indeed, these R functions each call into different C code,
C_text(), vs C_title() vs C_mtext()  
and it seems C_text() does something not as well as the other two.
All three function's source code is in <Rsrc>/src/library/graphics/src/plot.c

Maybe Paul can have a look?

It seems to have something to do with adjustment values, and the default:

plot( 1, 1 ) text(1,1, "with ä", adj = c( 0, 0 ) ) # Does not hang text(1,1, "with ä", adj = c( 0, 1 ) ) # Does not hang text(1,1, "with ä", adj = c( 1, 0 ) ) # Does not hang text(1,1, "with ä", adj = c( 1, 1 ) ) # Does not hang text(1,1, "with ä", adj = c( 0.5, 0.5 ) ) # Does not hang

text(1,1, "with ä", adj = NULL ) # DOES HANG


METADATA

MichaelChirico commented 4 years ago

The special code for handling the NULL adjustment in plot.c seems to be

PROTECT(adj = CAR(args));
if (isNull(adj) || (isNumeric(adj) && length(adj) == 0)) {
adjx = gpptr(dd)->adj;
adjy = NA_REAL;
}

and the NA_REAL may be the cause since

plot( 1, 1 )
text( 1, 1, "é", adj = c( 1, NA ) )

does also hang, but

text( 1, 1, "é", adj = c( NA, 1 ) )

does...


METADATA

MichaelChirico commented 4 years ago

(does not, for the second, sorry)


METADATA

MichaelChirico commented 4 years ago

Thanks for the report, fixed in R-devel 77638.


METADATA