Jeff Duntemann's Contrapositive Diary Rotating Header Image

assembly

A libc Mystery

As most of you know by now, I’m hard at work on the x64 edition of my assembly book, to be called X64 Assembly Language Step By Step. I’m working on the chapter where I discuss calling functions in libc from assembly language. The 2009 edition of the book was pure 32-bit x86. Parameters were passed to libc functions mostly by pushing them on the stack, which required cleaning up the stack after each call, etc.

Calling conventions in x64 are radically different. The first six parameters to any function are passed in registers. (More than six and you have to start pushing them on the stack.) The first parameter goes in RDI, the second in RSI, the third in RDX, and so on. When a function returns a single value, that value is passed back in RAX. This allows a lot more to be done without fooling with the stack.

Below is a short example program that makes four calls to libc functions: Two calls to puts(), a call to time, and a call to ctime. Here’s the makefile for the program:

showtime: showtime.o
        gcc showtime.o -o showtime -no-pie
showtime.o: showtime.asm 
        nasm -f elf64 -g -F dwarf showtime.asm -l showtime.lst

I’ve used this makefile for other example programs that call libc functions, and they all work. So take a look:

section .data
        timemsg db    "The timestamp is: ",0
        timebuf db    28,0   ; not useed yet
        time1   dq    0      ; time_t stored here.

section .bss

section .text

extern  time
extern  ctime
extern  puts
global  main

main:
        push rbp            ; Prolog    
        mov rbp,rsp

        mov rdi,timemsg     ; Put address of message in rdi
        call puts           ; call libc function puts
               
        xor rax,rax         ; Zero rax
        call time           ; time returns time_t value in rax        
        mov [time1],rax     ; Save time_t value to var time1
        
        mov rdi,time1       ; Copy pointer to time_t value to rdi
        call ctime          ; Returns ptr to the date string in rax

        mov rdi,rax         ; Copy pointer to string into rdi
        call puts           ; Print ctime's output string
        
        mov rsp,rbp         ; Epilog
        pop rbp
        
        ret                 ; Return from main()

Not much to it. There are four sections, not counting the prolog and epilog: The program prints an intro message using puts, then fetches the current time in time_t format, then uses ctime to convert the time_t value to the canonical human-readable format, and finally displays the date string. All done.

So what’s the problem? When the program hits the second puts call, it hangs, and I have to hit ctrl-z to break out of it. That’s peculiar enough, given how many times I’ve successfully used puts, time, and ctime in short examples.

The program assembles and links without problems, using the makefile shown above the program itself. I’ve traced it in a debugger, and all the parameters passed into the functions and their return values are as they should be. Even in a debugger, when the code calls the second instance of puts, it hangs.

Ok. Now here’s the really weird part: If you comment out one of the two puts calls (it doesn’t matter which one) the program doesn’t hang. One of the lines of text isn’t displayed but the calls to time and ctime work normally.

I’ve googled the crap out of this problem and haven’t come up with anything useful. My guess is that there’s some stack shenanigans somewhere, but all the register values look fine in the debugger, and the pointer passed back in rax by ctime does indeed point to the canonical null-terminated text string. The prolog creates the stack frame, and the epilog destroys it. My code doesn’t push anything between the prolog and epilog. All it does is make four calls into libc. It can successfully make three calls into libc…but not four.

Do you have to clean up the stack somehow after a plain vanilla x64 call into libc? That seems unlikely. And if so, why doesn’t the problem happen when the other three calls take place?

Hello, wall. Anybody got any suggestions?

SASM Crashes on “Section” in a Comment

As most of you know, I’m grinding along on the fourth edition of my book Assembly Language Step By Step, updated to cover x64. I’m using the SASM IDE for the example code because it provides seamless visual debugging using a front-end to gdb. Back in 2009 I created the third edition, and incorporated the Insight debugger front end for visual debugging. A month or so after the book appeared, Insight vanished from the Linux world. I tried a lot of debuggers and editors before I discovered SASM. It’s treated me very well.

Until today.

Now, I’ve been programming since 1970, in a lot of languages, on a lot of platforms, and I’ve made a lot of mistakes. Finding those mistakes is what debugging is about. Today, I was working on a short example program for the book. When I finished it, I clicked the Build button. It built as it should. I needed to single-step it to verify something about local labels, but when I clicked the debug button, SASM crashed. As Shakespeare would have put it, SASM died and gave no sign. The whole IDE just vanished. I tried it again. Same thing. I rebooted Linux. Same thing.

Puzzled doesn’t quite capture it. I loaded another example program from the book. It built and debugged without any trouble. I loaded example after example, and they all worked perfectly. Then I copied the source from the malfunctioning example into a file called crashtest.asm, and began cutting things out of it. I got it down to a start label and a SYSCALL to the exit function. Still blew SASM away.

Most of what was left was comments. I did a ctrl-X to cut the comment header onto the clipboard. Save, build, debug–and it worked perfectly.No crash, no errors, no problemo.

Soooooooo…….something in a comment header crashed the IDE? That would be a new one. So I dropped the comment header back into the file from the clipboard and started cutting out lines, one by one. I narrowed it down to one comment line, properly begun with a semicolon and containing no weird characters. The line that crashed SASM was this:

;         .bss sections.

I cut out the spaces and the period. No change. I cut out “.bss”. No change. I was left with the word “sections.” On a hunch, I lopped off the “s”. No change. Then I lopped off the “n”. Suddenly, it all worked.

SASM was crashing on a comment containing the word “section.” I verified by deleting the line entirely and typing it in again. Crash!

I stared at the damned thing for a long time. I loaded a couple of my other examples, and dropped the offending comment header into them. No problems. Twenty minutes later, I noticed something: In crashtest.asm, the fragment of comment header text was below the three section markers:

section.bss
section.data
section.text

; section

Now, in my other examples, the ones that didn’t crash, the comment header was above the three section markers. So I went back to crashtest.asm, and moved the comment header to the very beginning of the file, above the section markers. Suddenly everything worked. No crashes.

WTF? I assembled the offending crashtest binary from the command line without trouble. I loaded it into gdb from the command line and messed with it. No trouble.

I wrote this entry not for answers so much as to provide a report that other SASM users can find in search engines. There are things about SASM that aren’t ideal. Sure. But I’ve never seen it crash before. I’ll see if I can send the crashtest.asm to the people who created SASM. I’m sure it’s just a bug. But it’s the weirdest damfool bug I’ve uncovered in a whole lot of years!

Problems with SASM on Linux Mint

I’m scoping out a fourth edition of my book, Assembly Language Step by Step. I got wind of a simple FOSS utility that could be enormously useful in that effort: SASM (SimpleASM), which is an IDE created specifically for assembly-language work. It’s almost ideal for what I need: Simple, graphical, with a surprisingly sophisticated text editor and a graphical interface to GDB. It works with NASM, my assembler of choice. I want to use it as the example code IDE for the book. I installed it without effort on Windows, which is why I decided to use it. But I want to use it on Linux.

Alas, I’ve been unable to get it to install and run on Linux Mint 19 (Tara) using the Cinnamon desktop.

I’ve installed a lot of things on Linux Mint, all of them in the form of Debian packages. (.deb files.) I downloaded the SASM .deb file for Mint 19, and followed instructions found on the Web. There is a problem with dependencies that I just don’t understand.

I got it installed once but it wouldn’t run. I uninstalled it, and then it refused to reinstall.

Keep in mind that I am not a ‘leet Linux hacker. I’m a teacher, and most of what I teach is computing and programming for newcomers. The problem may be obvious to Linux experts but not to me. Most of the software I’ve installed on Mint came from repositories. SASM is a .deb download.

So. Does anybody else use it? If you’ve got Mint on a partition somewhere, could you try downloading it and installing it? I need to know if the problem is on my side of the screen or the other side.

Thanks in advance for any advice you might offer.

Odd Lots

  • I hit a milestone the other day: 40,000 words on Ten Gentle Opportunities, which is at least halfway there and maybe (if I’m willing to settle for a 75,000 word story) more than halfway.
  • One of my readers sent a link to a page describing how to install the Insight debugger under Linux Mint. As my ASM freak friends will recall, I no sooner described Insight in Assembly Language Step By Step, Third Edition than Debian pulled it out of their distribution. Supposedly this method will also work for newer versions of Ubuntu. I need to test the repository under both distros, and will report when I do.
  • There’s a new nova in Sagittarius. (Is that redundant?) Mag 7.8–which is easy to see with binoculars, if you can separate it from the stellar mosh pit in which it appeared. Thanks to Pete Albrecht for the link.
  • Michael Covington sent a Google Ngram for the words “whosever” and “whoever’s” indicating that “whosever” has been on the run for a couple of centuries. It became the minority player about 1920 and has been down in the mud since about 1960.
  • Ok, I agree: This is the most brilliant kitchen gadget since the salad spinner. Or before.
  • I used to do this a lot, though I haven’t done it since 1977: pull the guts out of a photocopier. This guy’s blog, by the way, is news to me but should be on every techie’s blogroll. (Thanks to Jack Smith K8ZOA for the link.)
  • Haven’t heard much about software radio recently. Ars Technica just had a nice overview piece on it. The hardware keeps getting better, but all the promised weirdness (including new types of pirate radio) hasn’t happened yet. My theory: Wi-Fi is just a better weirdness magnet.
  • Foxconn is releasing a fanless nano-PC toward the end of summer, and I like the looks of it, at least if it’s got something better than an Atom in it. Roughly 7.5″ X 5.25″ X 1.5″. No optical drive. 5-in-1 card reader on the front panel. Under $300.
  • Talk about nutty brilliance for film promotion: RC drones in the shape of superhero-style flying people to hype the film Chronicle, which is evidently about…flying people. (Thanks to Pete Albrecht for the link.)
  • To inflate a Buckyball, just use a laser.
  • This sweet merlot (scroll down) was lots better than I thought it would be, especially for a hot summer evening’s barbecue. May be hard to find outside Colorado. No least hint of concord grape, for you mutant-blueberry purists. About $15.
  • Yet another sign that we may be winning the Fat Wars: Fat-free dressing is bad for you.
  • Still yet another sign may be that the grocery store near our condo outside Chicago carries a sort of spreadable lard called “smalec.” This is the best-kept secret in the food world; it took me ten minutes to even find a picture of it. It was brought here by Polish immigrants and is no less healthy than butter, though I have no clue as to its taste.
  • As if we didn’t have enough to worry about, well, the latest home hazard is swallowing loose bristles from your grill brush. My brush is at least five years old and failing. Looking for another technique. (Again, thanks to Pete Albrecht for pointing it out.)
  • This sure sounds like a hoax, but there could be a zombie apocalypse theme park in Detroit’s future. The concept suggests that time’s about up for the zombie craze, so I’d better get my novel (which contains dancing zombies) shambling on to completion before the whole thing caves in.