~ubuntu-branches/ubuntu/saucy/strace/saucy-proposed

« back to all changes in this revision

Viewing changes to util.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Vogt
  • Date: 2009-05-05 10:21:37 UTC
  • mfrom: (0.1.6 upstream) (2.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20090505102137-ransgzeynrwa2yww
Tags: 4.5.18-1ubuntu1
* Merge from debian unstable, remaining changes:
  - Add lpia as supported architecture

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
31
31
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32
32
 *
33
 
 *      $Id: util.c,v 1.77 2008/07/18 01:19:36 roland Exp $
 
33
 *      $Id: util.c,v 1.79 2008/08/06 21:43:35 kratochvil Exp $
34
34
 */
35
35
 
36
36
#include "defs.h"
407
407
 
408
408
static char path[MAXPATHLEN + 1];
409
409
 
 
410
/*
 
411
 * Quote string `instr' of length `size'
 
412
 * Write up to (3 + `size' * 4) bytes to `outstr' buffer.
 
413
 * If `len' < 0, treat `instr' as a NUL-terminated string
 
414
 * and quote at most (`size' - 1) bytes.
 
415
 */
410
416
static int
411
417
string_quote(const char *instr, char *outstr, int len, int size)
412
418
{
417
423
        if (xflag > 1)
418
424
                usehex = 1;
419
425
        else if (xflag) {
 
426
                /* Check for presence of symbol which require
 
427
                   to hex-quote the whole string. */
420
428
                for (i = 0; i < size; ++i) {
421
429
                        c = ustr[i];
422
 
                        if (len < 0 && i == size - 2 && c != '\0')
423
 
                                ++i;
424
 
                        if (len < 0 && c == '\0')
425
 
                                break;
 
430
                        /* Check for NUL-terminated string. */
 
431
                        if (len < 0) {
 
432
                                if (c == '\0')
 
433
                                        break;
 
434
                                /* Quote at most size - 1 bytes. */
 
435
                                if (i == size - 1)
 
436
                                        continue;
 
437
                        }
426
438
                        if (!isprint(c) && !isspace(c)) {
427
439
                                usehex = 1;
428
440
                                break;
433
445
        *s++ = '\"';
434
446
 
435
447
        if (usehex) {
 
448
                /* Hex-quote the whole string. */
436
449
                for (i = 0; i < size; ++i) {
437
450
                        c = ustr[i];
438
 
                        if (len < 0 && c == '\0')
439
 
                                break;
 
451
                        /* Check for NUL-terminated string. */
 
452
                        if (len < 0) {
 
453
                                if (c == '\0')
 
454
                                        break;
 
455
                                /* Quote at most size - 1 bytes. */
 
456
                                if (i == size - 1)
 
457
                                        continue;
 
458
                        }
440
459
                        sprintf(s, "\\x%02x", c);
441
460
                        s += 4;
442
461
                }
443
462
        } else {
444
463
                for (i = 0; i < size; ++i) {
445
464
                        c = ustr[i];
446
 
                        if (len < 0 && i == size - 2 && c != '\0')
447
 
                                ++i;
448
 
                        if (len < 0 && c == '\0')
449
 
                                break;
 
465
                        /* Check for NUL-terminated string. */
 
466
                        if (len < 0) {
 
467
                                if (c == '\0')
 
468
                                        break;
 
469
                                /* Quote at most size - 1 bytes. */
 
470
                                if (i == size - 1)
 
471
                                        continue;
 
472
                        }
450
473
                        switch (c) {
451
474
                                case '\"': case '\\':
452
475
                                        *s++ = '\\';
495
518
        return i == size;
496
519
}
497
520
 
 
521
/*
 
522
 * Print path string specified by address `addr' and length `n'.
 
523
 * If path length exceeds `n', append `...' to the output.
 
524
 */
498
525
void
499
526
printpathn(struct tcb *tcp, long addr, int n)
500
527
{
 
528
        if (!addr) {
 
529
                tprintf("NULL");
 
530
                return;
 
531
        }
 
532
 
 
533
        /* Cap path length to the path buffer size,
 
534
           and NUL-terminate the buffer. */
501
535
        if (n > sizeof path - 1)
502
536
                n = sizeof path - 1;
503
 
 
504
 
        if (addr == 0) {
505
 
                tprintf("NULL");
506
 
                return;
507
 
        }
508
 
 
509
537
        path[n] = '\0';
 
538
 
 
539
        /* Fetch one byte more to find out whether path length > n. */
510
540
        if (umovestr(tcp, addr, n + 1, path) < 0)
511
541
                tprintf("%#lx", addr);
512
542
        else {
515
545
 
516
546
                if (trunc)
517
547
                        path[n] = '\0';
518
 
                if (string_quote(path, outstr, -1, n + 1) || trunc)
 
548
                (void) string_quote(path, outstr, -1, n + 1);
 
549
                if (trunc)
519
550
                        strcat(outstr, "...");
520
551
                tprintf("%s", outstr);
521
552
        }
527
558
        printpathn(tcp, addr, sizeof path - 1);
528
559
}
529
560
 
 
561
/*
 
562
 * Print string specified by address `addr' and length `len'.
 
563
 * If `len' < 0, treat the string as a NUL-terminated string.
 
564
 * If string length exceeds `max_strlen', append `...' to the output.
 
565
 */
530
566
void
531
567
printstr(struct tcb *tcp, long addr, int len)
532
568
{
538
574
                tprintf("NULL");
539
575
                return;
540
576
        }
541
 
        if (!str) {
542
 
                if ((str = malloc(max_strlen + 1)) == NULL
543
 
                    || (outstr = malloc(4*max_strlen
544
 
                                        + sizeof "\"\"...")) == NULL) {
545
 
                        fprintf(stderr, "out of memory\n");
546
 
                        tprintf("%#lx", addr);
547
 
                        return;
548
 
                }
 
577
        /* Allocate static buffers if they are not allocated yet. */
 
578
        if (!str)
 
579
                str = malloc(max_strlen + 1);
 
580
        if (!outstr)
 
581
                outstr = malloc(4 * max_strlen + sizeof "\"...\"");
 
582
        if (!str || !outstr) {
 
583
                fprintf(stderr, "out of memory\n");
 
584
                tprintf("%#lx", addr);
 
585
                return;
549
586
        }
550
587
 
551
588
        if (len < 0) {
 
589
                /*
 
590
                 * Treat as a NUL-terminated string: fetch one byte more
 
591
                 * because string_quote() quotes one byte less.
 
592
                 */
552
593
                size = max_strlen + 1;
 
594
                str[max_strlen] = '\0';
553
595
                if (umovestr(tcp, addr, size, str) < 0) {
554
596
                        tprintf("%#lx", addr);
555
597
                        return;
556
598
                }
557
599
        }
558
600
        else {
559
 
                size = MIN(len, max_strlen + 1);
 
601
                size = MIN(len, max_strlen);
560
602
                if (umoven(tcp, addr, size, str) < 0) {
561
603
                        tprintf("%#lx", addr);
562
604
                        return;
563
605
                }
564
606
        }
565
607
 
566
 
        if (string_quote(str, outstr, len, size))
 
608
        if (string_quote(str, outstr, len, size) &&
 
609
            (len < 0 || len > max_strlen))
567
610
                strcat(outstr, "...");
568
611
 
569
612
        tprintf("%s", outstr);
1284
1327
#ifndef CLONE_VFORK
1285
1328
# define CLONE_VFORK     0x00004000
1286
1329
#endif
 
1330
#ifndef CLONE_VM
 
1331
# define CLONE_VM        0x00000100
 
1332
#endif
1287
1333
#ifndef CLONE_STOPPED
1288
1334
# define CLONE_STOPPED   0x02000000
1289
1335
#endif
1300
1346
static int
1301
1347
arg_setup(struct tcb *tcp, arg_setup_state *state)
1302
1348
{
1303
 
        unsigned long *bsp, cfm, sof, sol;
 
1349
        unsigned long cfm, sof, sol;
 
1350
        long bsp;
1304
1351
 
1305
 
        if (ia32)
 
1352
        if (ia32) {
 
1353
                /* Satisfy a false GCC warning.  */
 
1354
                *state = NULL;
1306
1355
                return 0;
 
1356
        }
1307
1357
 
1308
 
        if (upeek(tcp->pid, PT_AR_BSP, (long *) &bsp) < 0)
 
1358
        if (upeek(tcp->pid, PT_AR_BSP, &bsp) < 0)
1309
1359
                return -1;
1310
1360
        if (upeek(tcp->pid, PT_CFM, (long *) &cfm) < 0)
1311
1361
                return -1;
1312
1362
 
1313
1363
        sof = (cfm >> 0) & 0x7f;
1314
1364
        sol = (cfm >> 7) & 0x7f;
1315
 
        bsp = ia64_rse_skip_regs(bsp, -sof + sol);
 
1365
        bsp = (long) ia64_rse_skip_regs((unsigned long *) bsp, -sof + sol);
1316
1366
 
1317
 
        *state = bsp;
 
1367
        *state = (unsigned long *) bsp;
1318
1368
        return 0;
1319
1369
}
1320
1370
 
1533
1583
#ifdef SYS_clone2
1534
1584
        case SYS_clone2:
1535
1585
#endif
1536
 
                /* ia64 calls directly `clone (CLONE_VFORK)' contrary to
1537
 
                   x86 SYS_vfork above.  Even on x86 we turn the vfork
1538
 
                   semantics into plain fork - each application must not
1539
 
                   depend on the vfork specifics according to POSIX.  We
1540
 
                   would hang waiting for the parent resume otherwise.  */
 
1586
                /* ia64 calls directly `clone (CLONE_VFORK | CLONE_VM)'
 
1587
                   contrary to x86 SYS_vfork above.  Even on x86 we turn the
 
1588
                   vfork semantics into plain fork - each application must not
 
1589
                   depend on the vfork specifics according to POSIX.  We would
 
1590
                   hang waiting for the parent resume otherwise.  We need to
 
1591
                   clear also CLONE_VM but only in the CLONE_VFORK case as
 
1592
                   otherwise we would break pthread_create.  */
 
1593
 
1541
1594
                if ((arg_setup (tcp, &state) < 0
1542
1595
                    || set_arg0 (tcp, &state,
1543
1596
                                 (tcp->u_arg[arg0_index] | CLONE_PTRACE)
1544
 
                                 & ~CLONE_VFORK) < 0
 
1597
                                 & ~(tcp->u_arg[arg0_index] & CLONE_VFORK
 
1598
                                     ? CLONE_VFORK | CLONE_VM : 0)) < 0
1545
1599
                    || arg_finish_change (tcp, &state) < 0))
1546
1600
                    return -1;
1547
1601
                tcp->flags |= TCB_BPTSET;