When I remotely login a SLURM interactive node, emacs will sometimes garble the screen. As I describe below, I think the issue is that the SLURM interactive node is messing up the Enquiry/acknowledgment terminal signals and some characters are getting dropped causing glitches.
Setup
Computer that I actually interact with: MacBook Air (10.13.2)
Terminal: iTerm2 Build 3.1.7
ssh to cluster
SLURM interactive node (i.e. srun --nodes=1 ... --pty /bin/bash)
emacs: GNU Emacs 27.1 used in terminal mode (i.e. emacs -nw)
Sometimes when the screen re-draws, it gets garbled:
It seems to happen more when the there are many panes or moving around lots of text.
Based on this part of the emacs documentation, I tried using C-l (recenter-top-bottom) to re-draw the screen, and that temporarily fixes the current glitch.
By setting $TERM=screen or $TERM=xterm-256color in my .bash-profile I see different color schemes, but the glitches persist.
Note, I am only seeing the glitches when I login to the interactive node, not from the head node on the cluster. Using the fact that it is ok on the loging node, this can provide useful diagnostic information. This makes me suspect that the issue is that the ENQ/ACK or pad-timing for so characters sent from the cluster are getting dropped. This is discussed in the documentation for the tack terminfo diagnostics program.
Using tack from both the login node and the interactive node give the same values
$ tack
Using terminfo from: /home/maom/opt/miniconda3/share/terminfo/x/xterm-256color
Name: xterm-256color|xterm with 256 colors
\r ^M (cr) = ^M
\n ^J (ind) = ^J
\b ^H (cub1) = ^H
\t ^I (ht) = ^I
(clear) = ^[[H^[[2J
(home) = ^[[H
ENQ (u9) = ^[[c
ACK (u8) = ^[[?1;2c
Terminal size: 204 x 52. Baud rate: 38400. Frame size: 10.0
Using the Baudrate test on the login node:
1600949 characters per second. Baudrate 52 Done
Using the Baudrate test on the interactive node the characters per second is about 30% slower:
1090426 characters per second. Baudrate 52 Done
And, using the test ENQ/ACK handshake on the login node gives:
Testing ENQ/ACK, standby...
This program expects the ENQ sequence to be answered with the ACK character. This will help the program reestablish synchronization when the terminal is overrun with data.
ENQ sequence from (u9): ^[[c
ACK received: ^[[?1;2c
Length of ACK 7. Expected length of ACK 7.
Terminating character found in (u8): c
while using the test ENQ/ACK handshake on the interactive node node gives:
Testing ENQ/ACK, standby...
ACK terminating character: c
Is there someway I can update the terminfo to fix the glitches work with the cluster admin support to work around the issue?
I have experienced the same problem, and I don't know the best solution, but this could help. First, when you do srun it is better to pass -li on bash:
srun --nodes=1 ... --pty /bin/bash -li
This will make sure it loads the interactive bash profile you will usually open when you normally login.
This does not fix the issue completely for me, but but if I do tmux in the interactive session and then run emacs, then I don't have garbling problem.
Related
Yesterday, I :q'd Vim to try Emacs for a while. I've started using Elisp (which is a hundred times better than VimScript), but even when I first installed it (via yum), and had changed nothing, it took about 30 seconds to start, and still does (both GUI and -nw).
I checked the *Messages* buffer:
Loading /usr/share/emacs/site-lisp/site-start.d/desktop-entry-mode-init.el (source)...done
Loading /usr/share/emacs/site-lisp/site-start.d/rpmdev-init.el (source)...done
The files seem to be specific to the RPM package I installed. I tried changing their names, yet there was no difference. It still takes 30 seconds.
I've solved it partially by never exiting emacs (I only suspend it) and trying to do everything in it, but it would be nice to occasionally open two Emacs's, especially since I have a tendency to use my terminal emulator's split function rather than something like tmux.
I realized that Emacs would load slower than Vim, but this seems ridiculous for a fresh install. Has anybody got any idea what's going on?
Thanks!
Emacs's PROBLEM file says:
*** Emacs startup on GNU/Linux systems (and possibly other systems) is slow.
This can happen if the system is misconfigured and Emacs can't get the
full qualified domain name, FQDN. You should have your FQDN in the
/etc/hosts file, something like this:
127.0.0.1 localhost
129.187.137.82 nuc04.t30.physik.tu-muenchen.de nuc04
The way to set this up may vary on non-GNU systems.
This "slow startup" typically comes from a timeout, and 30s sounds about right.
As a side note: the DNS lookup that causes this slow down was considered important/useful back in the days where (almost) all machines had a static IP address. Nowadays the info gathered this way does not justify the effort, so starting with Emacs-25, Emacs does not perform this DNS lookup, so this problem should simply not exist any more.
Okay, I have a (quirky and temporary) solution. I have to run dhclient em1 to access the internet, which makes Emacs take 30 seconds to load, probably because of some timeout. So, having already run dhclient em1, I use a shell script to launch Emacs that does the following:
sudo pkill dhclient
sudo ifconfig em1 down
emacs -nw -daemon 2> /dev/null
sudo ifconfig em1 up
sudo dhclient em1
That disables networking, launches Emacs as a daemon, and re-enables networking. It's ugly, but it works for now. If anybody else has a better answer, I'd be happy to hear it. Of course, em1 would have to be replaced by your Ethernet device (probably eth0, I guess).
I had a smilar problem with emacs taking about 15 seconds for startup. In my case the reason was a DNS timeout. For some reason, with my dormitory DNS, a failed reverse lookup (host 127.0.0.1) takes about 10 seconds. Replacing the DNS server by the google nameserver (8.8.8.8) produces an almost instant "not found: 3(NXDOMAIN)" response. At the same time, emacs's startup time went down to less than 2 seconds. Thanks #Stefan who pointed me into the direction of DNS problems.
Edit: adding the google nameserver as additional NS in Network Manager also does the job. (i.e. when your resolv.conf has the NSs in this order:
nameserver a.b.c.d
nameserver 8.8.8.8
)
I have a large repository of C++ code on a remote cluster (linux OS). When I need to work on this code from my home computer (Ubuntu OS), I try to access these codes through emacs on X windows. However the X window connection is very slow making the editing a painful process. So I sometimes move files manually between my local drive and remote cluster to edit the files. My question is: is there a way to configure my local emacs, such that when I edit the file in my local space, it would automatically be backed up in the cluster where it can then be compiled?
UPDATE:1
I installed TRAMP and it works well for servers that can be connected directly. However I also have servers which can be connected only when I activate VPN. How to provide the VPN information to TRAMP to connect to this server?
The other question I had was how to stop the TRAMP when it waits for prompts from remote shell without having to kill the whole emacs buffer.
This is typically a use case where TRAMP would be useful.
Instead of connecting to the server using SSH and opening Emacs there with X forwarding, run Emacs on your box and open your files remotely using TRAMP. For example:
C-xC-f/ssh:user#host:/remote/path/to/the/fileRET
This way, your Emacs process runs locally, but all file operations (e.g. save, revert, ...) are forwarded to the server, and all shell commands issued from TRAMP buffers also run on the remote server (this includes M-x compile)
UPDATE:1
When TRAMP hangs waiting for a remote shell prompt (which tends to happen frequently for reasons which are still obscure to me), I usually kill the underlying ssh process (htop with tree-like view is a good tool to do this) . TRAMP notices this and automatically respawns the killed process to resume operations.
Wouldn't it be easier to run Emacs in a console on the remote server? All Emacs functions can be access via the keyboard and once you get used to the key combinations it usually works out faster.
That way you will be running faster than forwarding an X session - running in a console is what Emacs was designed for.
As an added bonus - if you get used to using Gnu screen - http://www.gnu.org/software/screen/ you can pick up your sessions exactly as they were if the connection drops. In fact with screen you can shutdown your laptop at the end of the day - login over SSH the next day and pick up all your 'screens' exactly as they were the day before. This will include any open editors, debug sessions etc.
Gnu screen is available as a package on Debian and probably most Linux distributions.
I am looking for assistance with the proper GDB / OpenOCD initializion and running commands (external tools) to use within Eclipse for flash and RAM debugging, as well as the proper modifications or additions that need to be incorporated in a makefile for flash vs RAM building for this MCU, if this matters of course.
MCU: STM32F103VET6
I am using Eclipse Helios with Zylin Embedded CDT, Yagarto Tools and Bins, OpenOCD 0.4, and have an Olimex ARM-USB-OCD JTAG adapter.
I have already configured the ARM-USB-OCD and added it as an external tool in Eclipse. For initializing OpenOCD I used the following command in Eclipse. The board config file references the stm32 MCU:
openocd -f interface/olimex-arm-usb-ocd-h.cfg -f board/stm32f10x_128k_eval.cfg
When I run this within Eclipse everything appears to be working (GDB Interface, OpenOCD finds the MCU, etc). I can also telnet into OpenOCD and run commands.
So, I am stuck on the next part; initialization and commands for flash and RAM debugging, as well as erasing flash.
I read through several tutorials, and scoured the net, but have not been able to find anything particular to this processor. I am new to this, so I might not be recognizing an equivalent product for an example.
I'm working with the same tool chain to program and debug a STM32F107 board. Following are my observations to get an STM32Fxxx chip programmed and debugged under this toolchain.
Initial Starting Point
So at this point you've got a working OpenOCD to ARM-USB-OCD connection and so you should be all set on that end. Now the work is on getting Eclipse/Zylin/Yagarto GDB combination to properly talk to the STM32Fxxx through the OpenOCD/Olimex connection. One thing to keep in mind is that all the OpenOCD commands to issue are the run mode commands. The configuration scripts and command-line options to invoke the OpenOCD server are configuration mode commands. Once you issue the init command then the server enters run mode which opens up the set of commands you'll need next. You've probably done it somewhere else but I tack on a '-c "init"' option when I call the OpenOCD server like so:
openocd -f /path to scripts/olimex-arm-usb-ocd-h.cfg -f /path to targets/stm32f107.cfg -c "init"
The following commands I issue next are done by the Eclipse Debug Configurations dialogue. Under the Zylin Embedded debug (Native) section, I create a new configuration, give it a name, Project (optional), and absolute path to the binary that I want to program. Under the Debugger tab I set the debugger to Embedded GDB, point to the Yagarto GDB binary path, don't set a GDB command file, set GDB command set to Standard, and the protocol to mi.
The Commands Tab - Connect GDB to OpenOCD
So the next tab is the Commands tab and that's where the meat of the issue lies. You have two spaces Initialize and Run. Not sure exactly what the difference is except to guess that they occur pre- and post-invocation of GDB. Either way I haven't noticed a difference in how my commands are run.
But anyway, following the examples I found on the net, I filled the Initialize box with the following commands:
set remote hardware-breakpoint limit 6
set remote hardware-watchoint-limit 4
target remote localhost:3333
monitor halt
monitor poll
First two lines tell GDB how many breakpoints and watchpoints you have. Open OCD Manual Section 20.3 says GDB can't query for that information so I tell it myself. Next line commands GDB to connect to the remote target at the localhost over port 3333. The last line is a monitor command which tells GDB to pass the command on to the target without taking any action itself. In this case the target is OpenOCD and I'm giving it the command halt. After that I tell OpenOCD to switch to asynchronous mode of operation. As some of the following operations take a while, it's useful not to have OpenOCD block and wait for every operation.
Sidenote #1: If you're ever in doubt about the state of GDB or OpenOCD then you can use the Eclipse debug console to send commands to GDB or OpenOCD (via GDB monitor commands) after invoking this debug configuration.
The Commands Tab - Setting up the User Flash
Next are commands I give in the Run commands section:
monitor flash probe 0
monitor flash protect 0 0 127 off
monitor reset halt
monitor stm32x mass_erase 0
monitor flash write_image STM3210CTest/test_rom.elf
monitor flash protect 0 0 127 on
disconnect
target remote localhost:3333
monitor soft_reset_halt
to be explained in the following sections...
Setting up Access to User Flash Memory
First I issue an OpenOCD query to see if it can find the flash module and report the proper address. If it responds that it found the flash at address 0x08000000 then we're good. The 0 at the end specifies to get information about flash bank 0.
Sidenote #2: The STM32Fxxx part-specific data sheets have a memory map in section 4. Very useful to keep on hand as you work with the chip. Also as everything is accessed as a memory address, you'll come to know this layout like the back of your hand after a little programming time!
So after confirming that the flash has been properly configured we invoke the command to turn off write protection to the flash bank. PM0075 describes everything you need to know about programming the flash memory. What you need to know for this command is the flash bank, starting sector, ending sector, and whether to enable or disable write protection. The flash bank is defined in the configuration files you passed to OpenOCD and was confirmed by the previous command. Since I want to disable protection for the entire flash space I specify sectors 0 to 127. PM0075 explains how I got that number as it refers to how the flash memory is organized into 2KB pages for my (and your) device. My device has 256KB of flash so that means I have 128 pages. Your device has 512KB of flash so you'll have 256 pages. To confirm that your device's write-protection has been disabled properly, you can check the FLASH_WRPR register at address 0x40022020 using the OpenOCD command:
monitor mdw 0x40022020
The resulting word that it prints will be 0xffffffff which means all pages have their write protection disabled. 0x00000000 means all pages have write protection enabled.
Sidenote #3: On the subject of the memory commands, I bricked my chip twice as I was messing with the option bytes at the block starting at address 0x1ffff800. First time I set the read protection on the flash (kind of hard to figure out what your doing if you do that), second time I set the hardware watchdog which prevented me from doing anything afterwards since the watchdog kept firing off! Fixed it by using the OpenOCD memory access commands. Moral of the story is: With great power comes great responsibility.... Or another take is that if I shoot myself in the foot I can still fix things via JTAG.
Sidenote #4: One thing that'll happen if you try to write to protected flash memory is the FLASH_SR:WRPRTERR bit will be set. OpenOCD will report a more user-friendly error message.
Erasing the Flash
So after disabling the write protection, we need to erase the memory that you want to program. I do a mass erase which erases everything, you also have the option to erase by sector or address (I think). Either way you need to erase first before programming as the hardware checks for erasure first before allowing a write to occur. If the FLASH_SR:PGERR bit (0x4002200c) ever gets set during programming then you know you haven't erased that chunk of memory yet.
Sidenote #5: Erasing a bit in flash memory means setting it to 1.
Programming Your Binary
The next two lines after erasure writes the binary image to the flash and reenables the write protection. There isn't much more to say that isn't covered by PM0075. Basically any error that occurs when you issue flash write_image is probably related to the flash protection not being disabled. It's probably NOT OpenOCD though if you're curious you can take enable the debug output and follow what it does.
GDB Debugging
So finally after programming I disconnect GDB from the remote connection and then reconnect it to the target, do a soft-reset, and my GDB is now ready to debug. This last part I just figured out last night as I was trying to figure out why, after programming, GDB wouldn't properly stop at main() after reset. It kept going off into the weeds and blowing up.
My current thinking and from what I read in the OpenOCD and GDB manuals is that the remote connection is, first and foremost, meant to be used between GDB and a target that has already been configured and running. Well I'm using GDB to configure before I run so I think the symbol table or some other important info gets messed up during the programming. The OpenOCD manual says that the server automatically reports the memory and symbols when GDB connects but all that info probably becomes invalid when the chip gets programmed. Disconnecting and reconnecting I think refreshes the info GDB needs to debug properly. So that has led me to create another Debug Configuration, this one just connects and resets the target since I don't necessarily need to program the chip every time I want to use GDB.
Whew! Done! Kind of long but this took me 3 weekends to figure out so isn't too terribly bad I think...
Final sidenote: During my time debugging I found that OpenOCD debug output to be invaluable to me understanding what OpenOCD was doing under the covers. To program a STM32x chip you need to unlock the flash registers, flip the right bits, and can only write a half-word at a time. For a while I was questioning whether OpenOCD was doing this properly but after looking through the OpenOCD debug output and comparing it against what the PM0075 instructions were, I was able to confirm that it did indeed follow the proper steps to do each operation. I also found I was duplicating steps that OpenOCD was already doing so I was able to cut out instructions that weren't helping! So moral of the story: Debug output is your friend!
I struggled getting JLink to work with a STM3240XX and found a statement in the JLink GDB server documentation saying that after loading flash you must issue a "target reset":
"When debugging in flash the stack pointer and the PC are set automatically when the target is reset after the flash download. Without reset after download, the stack pointer and the PC need to be initialized correctly, typically in the .gdbinit file."
When I added a "target reset" in the Run box of the debugger Setup of Eclipse, suddenly everything worked. I did not have this problem with a Kinetis K60.
The document also explains how to manually set the stack pointer and pc directly if you don't want to issue a reset. It may not be the disconnect/connect that solves the problem but the reset.
What i use after the last sentence in the Comannd Tab - 'Run' Commands, is:
symbol-file STM3210CTest/test_rom.elf
thbreak main
continue
The thbreak main sentence is what makes gdb stop at main.
I am trying to find a hook in Emacs, which should fire right before emacs server graceful shutdown.
I tried kill-emacs-query-functions, kill-emacs-hook, server-done-hook with elisp like :
(add-hook 'server-done-hook
'(lambda ()
(savehist-save)
)
)
... but none of them is called when OS shuts down, so history is not saved.
Maybe someone could give a hint?
P.S. I am on Gentoo Linux, emacs-vcs-23.2.9999 package, terminal only. For testing desired behaviour Emacs is stopped using start-stop-daemon utility.
Since Emacs 24.1, Emacs runs kill-emacs which runs the functions in kill-emacs-hook. So the question, and the rest of this answer, are only relevant to older versions.
The right place to run something before Emacs shuts down is either kill-emacs-query-function if you want to be able to cancel the shutdown or kill-emacs-hook if you don't. The problem you're facing is that your OS does not notify Emacs to shut down gracefully in a way that Emacs understands, or to look at it the other way, Emacs does not understand your OS's request to suht down gracefully.
A graceful way of shutting down Emacs 23 from the outside is to run emacsclient -n -e '(kill-emacs)'. That's obviously not a generic way of telling a program to shut down gracefully.
The normal way to shut down a process gracefully on unix is to send it a SIGHUP or SIGTERM signal. Unfortunately, Emacs treats almost all signals as fatal, and only runs an emergency auto save and no lisp code when it receives them. This is not configurable from lisp. A different behavior has been requested, but turned down.
A partial workaround (found here) is to run session saving hooks in delete-frame-functions. This hook is likely to be run before the system shutdown sequence, either when you close your last frame or when the X server dies (taking your terminals with them if you run Emacs in a terminal). Make sure you don't run the hook that kills the server in delete-frame-functions.
By the way, if you were going to use this exact hook, note that your code is a complicated way of writing (add-hook 'server-done-hook 'savehist-save), and that's not useful since there's already savehist-autosave in kill-emacs-hook.
This page from the Emacs manual describes a function called make-frame-on-display that allows you to access a remote Emacs session. My interest in this function is to use it to share buffers for pair programming remotely with a colleague.
From the page:
It is even possible to use this feature to let two or more users type simultaneously on the two displays, within the same Emacs job. In practice, however, the different users can easily interfere with each others' edits if they are not careful.
How exactly do I set this up? What do I need? What does my partner need? The details are not stated, but I don't know enough about Emacs to know where to start.
Is there any other way to get a shared Emacs session? This page from the Emacs Wiki refers to something called multi-tty. The questions I asked above also apply to this.
Which is better: multi-tty or make-frame-on-display?
I haven't tried multi-tty, but make-frame-on-display is pretty simple. You type M-x make-frame-on-display, hit return, then type the display you want the frame to show up on. For example:
I have my local host (thor) running emacs and I want to make a frame pop up on a machine called zeus, on its only X display (0.0). So I would type M-x make-frame-on-display<ret>zeus:0.0<ret>
All set!
You may need to configure the remote machine's X server to accept incoming connections from your machine with "xhost +thor". You may also need to configure its firewall to allow incoming connections on the X11 port, which is 6000. Keep in mind that X forwarding is not encrypted, so if you aren't working with someone on your LAN you may want to go through a VPN in order to keep things private.
Edited to fix brackets.
You can also have the person at zeus type ssh -X thor emacsclient -c.
Did you ever consider using GNU screen on a shared account for pair programming? It's dead easy to get it to work and you get to pick any console based editor you and your partner like (emacs, vim, joe, nano, zile, ...). However, this does of course not work with editors that cannot run inside a terminal.
To set it up, create a shared account on a computer running ssh. Then both log in to that account. One of the partners starts screen with
screen
and the other connects to it with
screen -x
where -x means "attach to a not detached screen session". The users can detach from their sessions w/ "C-a d".
Old question, new solution for anyone landed on this page from year 2016.
I set this up in Ubuntu 14.04 and it works perfectly:
Suppose I want to co-edit or demo some cool stuffs on emacs with my colleague Joe on the other end of the world.
Make sure an ssh server with emacs installed at either end. That is, either MyPC or JoePC must be a SSH server and have Emacs installed. From now on, let's say I asked Joe to install SSH server and Emacs on his computer.
Make sure byobu is installed on JoePC. Byobu supports both tmux and screen as backends (I prefer tmux for a more mordern and feature-rich).
I connect to JoePC with ssh remoteuser#joepc. No need for X-forwarding.
Open emacs from byobu-ssh terminal: TERM=xterm-256color && emacsclient --alternate-editor="" -t. One can make an alias for this command. I recommend this long command because it enables both better color support in the terminal and running Emacs in daemon mode. The daemon mode make it fast to close and reopen frames.
Now the magic unfold: Ask Joe to login with the same remoteuser I am loggin in; open the terminal and start byobu if it hasn't for him.
Start hacking or fumbling :-)
Comment:
Because the way byobu work. This approach works for any other program inside the byobu terminal.
This setup performs much better than Teamviewer or any other GUI remote desktop solutions.
Because the connection is through ssh to the remote server directly, it is as secure as the ssh conenction can offer.