Skip to content
This repository has been archived by the owner on Sep 22, 2022. It is now read-only.

crash in mdbx_env_info_ex if env wasn't used yet #171

Closed
Thermi opened this issue Mar 12, 2021 · 0 comments
Closed

crash in mdbx_env_info_ex if env wasn't used yet #171

Thermi opened this issue Mar 12, 2021 · 0 comments
Assignees
Labels

Comments

@Thermi
Copy link

Thermi commented Mar 12, 2021

Reproduced in master and devel branches.

  MDBX_envinfo envinfo;
  memset(&envinfo, 0, sizeof(envinfo));
  rc = mdbx_env_create(&env);
  if (rc != MDBX_SUCCESS) {
    fprintf(stderr, "mdbx_env_create: (%d) %s\n", rc, mdbx_strerror(rc));
    goto bailout;
  }
  rc = mdbx_env_info_ex(env, NULL, &envinfo, sizeof(envinfo));
  if (rc != MDBX_SUCCESS) {
    fprintf(stderr, "mdbx_env_info_ex: (%d) %s\n", rc, mdbx_strerror(rc));
    goto bailout;
  }

-> Debugging with gdb yields this information:

Program received signal SIGSEGV, Segmentation fault.
-----------------------------------------------------------------------------------------------------------------------[regs]
  RAX: 0x0000000000001000  RBX: 0x0000000000000000  RBP: 0x00007FFFFFFFDAC0  RSP: 0x00007FFFFFFFD9F8  o d I t s z A P c 
  RDI: 0x0000000000000000  RSI: 0x0000000000002000  RDX: 0x0000000000000000  RCX: 0x000000000000000C  RIP: 0x00007FFFF7F950AB
  R8 : 0x0000000000001000  R9 : 0x0000000000000000  R10: 0xFFFFFFFFFFFFF8D4  R11: 0x00007FFFF7F7C588  R12: 0x0000000000002000
  R13: 0x0000000000001000  R14: 0x000055555556AEB0  R15: 0x00007FFFFFFFDAC0
  CS: 0033  DS: 0000  ES: 0000  FS: 0000  GS: 0000  SS: 002B
-----------------------------------------------------------------------------------------------------------------------[code]
=> 0x7ffff7f950ab <mdbx_meta_mostrecent+27>:    mov    rcx,QWORD PTR [rdx+0xc4]
   0x7ffff7f950b2 <mdbx_meta_mostrecent+34>:    cmp    QWORD PTR [rdx+0x1c],rcx
   0x7ffff7f950b6 <mdbx_meta_mostrecent+38>:    lea    rax,[rdx+rax*1+0x14]
   0x7ffff7f950bb <mdbx_meta_mostrecent+43>:    lea    r8,[rdx+rsi*1+0x14]
   0x7ffff7f950c0 <mdbx_meta_mostrecent+48>:    cmovne rcx,r9
   0x7ffff7f950c4 <mdbx_meta_mostrecent+52>:    mov    rsi,QWORD PTR [rax+0xb0]
   0x7ffff7f950cb <mdbx_meta_mostrecent+59>:    cmp    QWORD PTR [rax+0x8],rsi
   0x7ffff7f950cf <mdbx_meta_mostrecent+63>:    cmovne rsi,r9
-----------------------------------------------------------------------------------------------------------------------------
mdbx_meta_mostrecent (mode=prefer_last, env=<optimized out>) at src/core.c:5118
5118      MDBX_meta *head = mdbx_meta_recent(mode, env, m0, m1);

valgrind yields this:

LANG=C valgrind ./mdbx_example 
==1173312== Memcheck, a memory error detector
==1173312== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1173312== Using Valgrind-3.16.1 and LibVEX; rerun with -h for copyright info
==1173312== Command: ./mdbx_example
==1173312== 
==1173312== Invalid read of size 8
==1173312==    at 0x487F0AB: unaligned_peek_u64 (core.c:145)
==1173312==    by 0x487F0AB: meta_txnid (core.c:4976)
==1173312==    by 0x487F0AB: mdbx_meta_txnid_fluid (core.c:4990)
==1173312==    by 0x487F0AB: mdbx_meta_ot (core.c:5045)
==1173312==    by 0x487F0AB: mdbx_meta_recent (core.c:5099)
==1173312==    by 0x487F0AB: mdbx_meta_mostrecent (core.c:5118)
==1173312==    by 0x48666A5: mdbx_env_info_ex (core.c:18383)
==1173312==    by 0x1091DC: main (example-mdbx.c:44)
==1173312==  Address 0xc4 is not stack'd, malloc'd or (recently) free'd
==1173312== 
==1173312== 
==1173312== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==1173312==  Access not within mapped region at address 0xC4
==1173312==    at 0x487F0AB: unaligned_peek_u64 (core.c:145)
==1173312==    by 0x487F0AB: meta_txnid (core.c:4976)
==1173312==    by 0x487F0AB: mdbx_meta_txnid_fluid (core.c:4990)
==1173312==    by 0x487F0AB: mdbx_meta_ot (core.c:5045)
==1173312==    by 0x487F0AB: mdbx_meta_recent (core.c:5099)
==1173312==    by 0x487F0AB: mdbx_meta_mostrecent (core.c:5118)
==1173312==    by 0x48666A5: mdbx_env_info_ex (core.c:18383)
==1173312==    by 0x1091DC: main (example-mdbx.c:44)
==1173312==  If you believe this happened as a result of a stack
==1173312==  overflow in your program's main thread (unlikely but
==1173312==  possible), you can try to increase the size of the
==1173312==  main thread stack using the --main-stacksize= flag.
==1173312==  The main thread stack size used in this run was 8388608.
==1173312== 
==1173312== HEAP SUMMARY:
==1173312==     in use at exit: 512 bytes in 1 blocks
==1173312==   total heap usage: 2 allocs, 1 frees, 73,216 bytes allocated
==1173312== 
==1173312== LEAK SUMMARY:
==1173312==    definitely lost: 0 bytes in 0 blocks
==1173312==    indirectly lost: 0 bytes in 0 blocks
==1173312==      possibly lost: 0 bytes in 0 blocks
==1173312==    still reachable: 512 bytes in 1 blocks
==1173312==         suppressed: 0 bytes in 0 blocks
==1173312== Rerun with --leak-check=full to see details of leaked memory
==1173312== 
==1173312== For lists of detected and suppressed errors, rerun with: -s
==1173312== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Speicherzugriffsfehler (Speicherabzug geschrieben)

Complete code from example (reproduced with modified example):

/* MDBX usage example
 *
 * Do a line-by-line comparison of this and sample-bdb.txt
 */

/*
 * Copyright 2015-2021 Leonid Yuriev <leo@yuriev.ru>.
 * Copyright 2017 Ilya Shipitsin <chipitsine@gmail.com>.
 * Copyright 2012-2015 Howard Chu, Symas Corp.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted only as authorized by the OpenLDAP
 * Public License.
 *
 * A copy of this license is available in the file LICENSE in the
 * top-level directory of the distribution or, alternatively, at
 * <http://www.OpenLDAP.org/license.html>.
 */

#include "../mdbx.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char *argv[]) {
  (void)argc;
  (void)argv;

  int rc;
  MDBX_env *env = NULL;
  MDBX_dbi dbi = 0;
  MDBX_val key, data;
  MDBX_txn *txn = NULL;
  MDBX_cursor *cursor = NULL;
  MDBX_envinfo envinfo;
  char sval[32];
  memset(&envinfo, 0, sizeof(envinfo));
  rc = mdbx_env_create(&env);
  if (rc != MDBX_SUCCESS) {
    fprintf(stderr, "mdbx_env_create: (%d) %s\n", rc, mdbx_strerror(rc));
    goto bailout;
  }
  rc = mdbx_env_info_ex(env, NULL, &envinfo, sizeof(envinfo));
  if (rc != MDBX_SUCCESS) {
    fprintf(stderr, "mdbx_env_info_ex: (%d) %s\n", rc, mdbx_strerror(rc));
    goto bailout;
  }

  debug:;
  rc = mdbx_env_set_geometry(env,
    0, // size_lower
    -1, // size_now
    INTPTR_MAX, // size_upper
    -1, // growth_step
    -1, // shrink_threshold
    -1); // pagesize
  if (rc != MDBX_SUCCESS) {
    fprintf(stderr, "mdbx_env_set_geometry: (%d) %s\n", rc, mdbx_strerror(rc));
    goto bailout;
  }
  rc = mdbx_env_open(env, "./example-db",
                     MDBX_NOSUBDIR | MDBX_COALESCE | MDBX_LIFORECLAIM, 0664);
  if (rc != MDBX_SUCCESS) {
    fprintf(stderr, "mdbx_env_open: (%d) %s\n", rc, mdbx_strerror(rc));
    goto bailout;
  }

  rc = mdbx_txn_begin(env, NULL, 0, &txn);
  if (rc != MDBX_SUCCESS) {
    fprintf(stderr, "mdbx_txn_begin: (%d) %s\n", rc, mdbx_strerror(rc));
    goto bailout;
  }
  rc = mdbx_dbi_open(txn, NULL, 0, &dbi);
  if (rc != MDBX_SUCCESS) {
    fprintf(stderr, "mdbx_dbi_open: (%d) %s\n", rc, mdbx_strerror(rc));
    goto bailout;
  }

  key.iov_len = sizeof(int);
  key.iov_base = sval;
  data.iov_len = sizeof(sval);
  data.iov_base = sval;

  sprintf(sval, "%03x %d foo bar", 32, 3141592);
  rc = mdbx_put(txn, dbi, &key, &data, 0);
  if (rc != MDBX_SUCCESS) {
    fprintf(stderr, "mdbx_put: (%d) %s\n", rc, mdbx_strerror(rc));
    goto bailout;
  }
  rc = mdbx_txn_commit(txn);
  if (rc) {
    fprintf(stderr, "mdbx_txn_commit: (%d) %s\n", rc, mdbx_strerror(rc));
    goto bailout;
  }
  txn = NULL;

  rc = mdbx_txn_begin(env, NULL, MDBX_TXN_RDONLY, &txn);
  if (rc != MDBX_SUCCESS) {
    fprintf(stderr, "mdbx_txn_begin: (%d) %s\n", rc, mdbx_strerror(rc));
    goto bailout;
  }
  rc = mdbx_cursor_open(txn, dbi, &cursor);
  if (rc != MDBX_SUCCESS) {
    fprintf(stderr, "mdbx_cursor_open: (%d) %s\n", rc, mdbx_strerror(rc));
    goto bailout;
  }

  int found = 0;
  while ((rc = mdbx_cursor_get(cursor, &key, &data, MDBX_NEXT)) == 0) {
    printf("key: %p %.*s, data: %p %.*s\n", key.iov_base, (int)key.iov_len,
           (char *)key.iov_base, data.iov_base, (int)data.iov_len,
           (char *)data.iov_base);
    found += 1;
  }
  if (rc != MDBX_NOTFOUND || found == 0) {
    fprintf(stderr, "mdbx_cursor_get: (%d) %s\n", rc, mdbx_strerror(rc));
    goto bailout;
  } else {
    rc = MDBX_SUCCESS;
  }
bailout:
  if (cursor)
    mdbx_cursor_close(cursor);
  if (txn)
    mdbx_txn_abort(txn);
  if (dbi)
    mdbx_dbi_close(env, dbi);
  if (env)
    mdbx_env_close(env);
  return (rc != MDBX_SUCCESS) ? EXIT_FAILURE : EXIT_SUCCESS;
}
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants