Visit Our UNIX and Linux User Community

[FreeBSD] ptrace( ) - Device busy

Thread Tools Search this Thread
Top Forums Programming [FreeBSD] ptrace( ) - Device busy
# 1  
Old 01-30-2003
[FreeBSD] ptrace( ) - Device busy

I'm trying to obtain process memory contents using ptrace( ) on FreeBSD 4.7. I know this is neither portable nor clean, yet I'd really like to get it to work... I read the manual help page and did a google search, but couldn't find anything helpful.
First, the code I'm using to read an integer:

#include <sys/types.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <unistd.h>
#include <signal.h>
#include <errno.h>
#include <stdio.h>

#define ERR( msg, pid ) do { \
                          fprintf( stderr, "%s: %s (errno = %d)\n", \
                            msg, strerror( errno ), errno ); \
                          waitpid( pid, NULL, 0 ); \
                          return 1; \
                        } while( 0 );

int main( ) {
  pid_t child;
  int   i;
  child = fork( );
  if( child == -1 ) {
    perror( "fork" );
    return 1;
  } else if( child == 0 ) {
    execl( "./foobar", NULL );
    perror( "execl" );
    return 1;
  printf( "Attaching to %d\n", child );
  rc = ptrace( PT_ATTACH, child, ( void* )0, 0 );
  if( rc == -1 ) {
    ERR( "ptrace", child );
  printf( "Stopping...\n" );
  if( kill( child, SIGSTOP ) != 0 ) {
    ERR( "kill", child );
  printf( "Attempting to read...\n" );
  rc = ptrace( PT_READ_I, child, ( void* )0, 0 );
  if( rc == -1 ) {
    ERR( "ptrace", child );
  printf( "0x0: %d\n", rc );
  return 0;

And the source for the exec'd ``foobar'':

#include <unistd.h>

int main( ) {
  pause( );
  return 0;

The output I get when I execute the program is this:

Attaching to 5994
Attempting to read...
ptrace: Device busy (errno = 16)

I have tried several variations using PT_READ_I and PT_READ_D (although my manual help page states these are identical on FreeBSD), using several addresses - I always get this error.
Can anyone see what I'm doing wrong here?
Thanks in advance.
# 2  
Old 01-30-2003
I can't actually try this, but that kill() immediately followed by a ptrace() really bothers me.

You seem to be thinking that the kill() system call will not return to the caller until after the signaled process has completed whatever action will result from the signal. Or something like that.

In any event, my guess is that you need to signal the child and then wait until it stops. Look at paragraph 1 of the ptrace man page: "the tracing process is expected to notice this via wait(2) or the delivery of a SIGCHLD signal..." Where are you doing that? Some time is required to actually stop a process, even one that is sleeping.

And look at the "ERRORS" section of the man page...only 3 possibilities. And only:
"A request (other than PT_ATTACH) specified a process that wasn't stopped"
really could apply here.

Hmmmm. Good thing you didn't unbuffer stdout. If you had, that printf might have slowed down the tracer enough that it might sometimes work and sometimes fail.
# 3  
Old 01-30-2003
Thanks for your reply!
I actually tried it using sleep( ) before, but that didn't have any effect. Using wait( ), as you suggested, did the trick. Now I have a new problem: If I pass low addresses as third parameter, I always get ``Bad address'' errors. While trying to find the root of this problem, I happened to pass the uninitialised variable ``i'' as address (I used it as loop counter before and when I commented that out, the value became, of course, undefined :-) )...
It worked! Strangely, the value of ``i'' was 671482112.
Quotation from the man page:

The addr argument specifies the address (in the traced process' virtual address space) at which the read is to be done. This address does not have to meet any alignment constraints.
I don't believe that my tiny ``foobar'' program uses > 640mb of memory. Even if this was an absolute address (contradicting the man page), I don't have that much. While I'm typing this, I have the program trying all ``addresses'' from 0 to 1000000000 - It's at 115xxxxxx now and no ``address'' was valid. What the heck is going here?

int i;
printf( "Attempting to read...\n" );
wait( NULL );
rc = ptrace( PT_READ_D, child, ( void* )i, 0 );
if( rc == -1 && errno ) {
  ERR( "ptrace", child );
printf( "%p: %d\n", ( void* )i, rc );

Attaching to 6487
Attempting to read...
0x28060100: -716130182

# 4  
Old 01-30-2003
It's awfully hard to help much on this since I don't have access to your system and this stuff varies a lot among kernels. But I'll try...

First, let's say that your pagesize is 4096 and your program needs 50 pages. So it is 50 * 4096 = 204800 bytes long. That does not mean that the first address is zero and the last is 204800. You can't make something like that work with any cpu. Typically the pages are arranged into segments and the segments are contiguous. But the segments will be scattered throughout the virtual address space. Think about malloc() and the underlying brk()/sbrk() calls. They need to be able to make the data segment grow. The stack must be able to change size dynamically. Maybe your program will map in a shared everything has to grow. Also remember that it is illegal to deference a null pointer. Put something at zero and rerefencing a null pointer becomes legal. And taking the address of whatever you put there would give you NULL. The c standard prohibits that taking the address of an object would result in a NULL. And memory is organized into pages. If you can't use the first byte, you can't you the first page.

So you need to know what address you need. It can be anywhere. You might try putting "int xyzzy=777" before the main in your little to-be-traced program. Then run the nm program on it. Since xyzzy is external in scope it should probably be in the symbol table. Get the address for it and plug that into your tracer program. Then see if you can get the value 777. I tend to think that will work.

By the way, I have never used ptrace() on any system, so I am not exactly a ptrace() expert. I am not going to be able to help write a debugger or anything.
# 5  
Old 01-31-2003
Ok, using addresses from nm works. Smilie I chose a ``null pointer'' fist because I thought the supplied parameter would be used as offset to the beginning of the first page (where the text segment starts, at ``NULL''). Apparently it isn't. Oh well, I guess it's time to read some source code (probably gdb).
Thanks again for your help!
# 6  
Old 01-31-2003
After sleeping on this, I think that I know how to to take this to the next level. The tracing program should be able to use nlist() on the executable of the child. This would enable it to programmaticly obtain the address of externals.

Previous Thread | Next Thread
Test Your Knowledge in Computers #33
Difficulty: Easy
In HTTPS, the letter 'S' stands for 'safe'.
True or False?

10 More Discussions You Might Find Interesting

1. UNIX for Beginners Questions & Answers

Mount : Device busy

mount -f nfs 1234:/export/ert /der/fr/ert mount : /der/fr/ert: device busy normally I will then do an fuser filesystem and kill the pids, which I did. now if I do an fuser /der/fr/ert I get the mount point and no pid > fuser /der/fr/ert /der/fr/ert: but it... (1 Reply)
Discussion started by: goya
1 Replies

2. HP-UX

Failed to open tape device /dev/rmt/0mn:Device busy (errno = 16)

Hi, Unable to make tape backup, please help. /opt/ignite/bin/make_tape_recovery -a /dev/rmt/?mn -I -v -m tar -x inc_entire=vg00 * Creating local directories for configuration files and archive. ======= 04/25/16 16:28:08 IST Started /opt/ignite/bin/make_tape_recovery. (Mon... (4 Replies)
Discussion started by: anuragr
4 Replies

3. Hardware

/dev/ttyS0: Device or resource busy

hello to everybody I have Ubuntu Lucid 10.04 installed on my Desktop and I have a PCI serial card in my computer and it has only one serial port. Actually I want to use this serial port for the serial communication and for that I executed this command : $ setserial -g /dev/ttyS and I... (0 Replies)
Discussion started by: piyush011
0 Replies

4. Solaris

CDROM will not eject - says device busy

Hi, I've seen similar posts on this board about ejecting CDROMs but I've tried the solutions people suggested but still cannot eject the CD. It's stuck in a production box so I can't reboot it... bash-3.00# eject -f cdrom /vol/dev/dsk/c0t0d0/sol_10_106_sparc/s0: Device busy bash-3.00#... (14 Replies)
Discussion started by: jimmy54321
14 Replies

5. UNIX Desktop Questions & Answers

cygwin error device or resource busy

Hello!!! My problem is: i'm trying to send At commands from Pc to mobile phone using bluetooth and cygwin and i would like to read the device's answers on the shell bash. And so, i open two terminals in this way: xterm & In the first i write: cat /dev/ttyS2 because the device is... (9 Replies)
Discussion started by: blianna
9 Replies

6. UNIX and Linux Applications

/dev/ttyS2 device or resource busy

Ciao a tutti!!! il mio problema questo: sto cercando di inviare dei comandi AT da PC a cellulare utilizzando il bluetooth e cygwin e vorrei visualizzare le risposte nella shell bash. Per farlo apro due terminali utilizzando le seguente istruzioni: xterm & Sul primo scrivo cat /dev/ttyS2 ... (1 Reply)
Discussion started by: blianna
1 Replies

7. UNIX Desktop Questions & Answers

cygwin /dev/ttyS2: Device or resource busy

Ciao a tutti!!! il mio problema questo: sto cercando di inviare dei comandi AT da PC a cellulare utilizzando il bluetooth e cygwin e vorrei visualizzare le risposte nella shell bash. Per farlo apro due terminali utilizzando le seguente istruzioni: xterm & Sul primo scrivo cat /dev/ttyS2 ... (0 Replies)
Discussion started by: blianna
0 Replies

8. UNIX for Dummies Questions & Answers

Device or resource busy??

Hi, I'm trying to do a sharity mount to mount a terastation network drive. I'm getting a Device or resource busy message after my mount command. Please see output below... # /usr/local/sharity3/bin/sharity mount smb://labbackup01/bakup_data /mnt/labbackup01 Device or resource busy.... (2 Replies)
Discussion started by: orahi001
2 Replies

9. HP-UX

Cannot umount - device busy

Anyone have any idea why I cannot umount a directory even though fuser shows no process attached to it? fuser -cu /data/oracle/GMPSHRDM/export /data/oracle/GMPSHRDM/export: umount /data/oracle/GMPSHRDM/export umount: cannot unmount /data/oracle/GMPSHRDM/export : Device busy umount:... (2 Replies)
Discussion started by: keelba
2 Replies

10. UNIX for Dummies Questions & Answers

umount, device busy, but..

I'm trying to unmount a file system, but umount says the device is busy. A fuser -c /myfs tells me that nothing on this fs is in use. Any idea? Oh, and btw, why isn't my signature beeing displayed? Show user's signature is enabled and I have entered one :/ (10 Replies)
Discussion started by: sTorm
10 Replies

Featured Tech Videos