cudaMalloc或cudaMemcpy上的分段错误

时间:2016-01-20 20:55:28

标签: c++ cuda segmentation-fault

CUDA编程的新手,并且极为困惑我为什么在以下代码中获得段错误:

  #include <cuda.h>
  #include <stdio.h>
  #include <stdint.h>
  #include <fstream>
  #include <iostream>
  #include <sstream>
  #include <string>

  using namespace std;

  typedef struct password_t{
      char word[56];
      size_t length;
  } password;

  typedef struct libEntry_t{
      uint8_t digest[16];
      password pwd;
  } libEntry;

  // Generates a library of passwords and their corresponding MD5 hashes
  //
  // Params:
  //    numPwds - the number of passwords for which to generate hashes
  //    pwds    - the list of passwords to hash
  //    library - the array in which to store the unhashed/hashed password library
  __global__ void generateLibraryKernel(int numPwds, password* pwds, libEntry* library)
  {
      // __device__ void cuda_md5(const password *pwd, uint8_t *digest) {
      int index = (blockIdx.x * blockDim.x) + threadIdx.x;
      uint8_t hashed[16];

      if (index < numPwds) {
        cuda_md5(&pwds[index], hashed);
        for (int j = 0; j < 16; j++) {
          library[index].digest[j] = hashed[j];
        }
        library[index].pwd = pwds[index];
      }
  }

  int crack_password (uint8_t* classified)
  {
      int count = 10;
      unsigned int mem_size = sizeof(password) * count;
      password *h_pwds = (password*) malloc(mem_size);

      ifstream inFile("passwords.txt");
      if (!inFile) {
        cerr << "File passwords.txt not found." << endl;
        return -1;
      }

      string line;
      int i;
      while (getline(inFile, line)) {
        if (line.empty()) continue;
        memcpy(h_pwds[i].word,line.c_str(),line.size());
        h_pwds[i].length = line.size();
        cout << "Password: " << h_pwds[i].word << "\n";
        cout << "Length: " << h_pwds[i].length << "\n";
        i++;
      }

      inFile.close();

      /***** KERNEL CONFIGURATION & MEMORY MANAGEMENT ******/
      password* d_pwds;
      cudaMalloc( (void**) &d_pwds, mem_size);
      cudaMemcpy( d_pwds, h_pwds, mem_size, cudaMemcpyHostToDevice);

      libEntry *h_library = (libEntry*) malloc(sizeof(libEntry) * count);

      libEntry* d_library;
      cudaMalloc( (void**) &d_library, sizeof(libEntry) * count);

      int h_numPwds = i;
      cout << "INT NUMPWDS: " << h_numPwds << "\n";

      int* d_numPwds;
      cudaMalloc( (void**) &d_numPwds, sizeof(int));
      cudaMemcpy( d_numPwds, &h_numPwds, sizeof(int), cudaMemcpyHostToDevice);

      /*unsigned int threads_per_block = 1024;
      dim3  grid(1024, 1, 1);
      dim3  threads(threads_per_block, 1, 1);

      // generateLibraryKernel(int numPwds, password* pwds, libEntry* library)
      generateLibraryKernel<<<grid, threads>>>(d_numPwds[0], d_pwds, d_library);

      cudaMemcpy( h_library, d_library, mem_size, cudaMemcpyDeviceToHost);*/

      return 0;
  }

  int main(int argc, char *argv[])
  {
      if (argc != 2) {
          fprintf(stderr, "usage: ./prog password\n");
          return 1;
      }

      crack_password((uint8_t*) argv[1]);
      cout << "Hack Password: " << argv[1] << "\n";
      return 0;
  }

我逐行完成了它,我相信它发生在以下几行:

      int* d_numPwds;
      cudaMalloc( (void**) &d_numPwds, sizeof(int));
      cudaMemcpy( d_numPwds, &h_numPwds, sizeof(int), cudaMemcpyHostToDevice);

当我评论上面的cudaMemcpy时,我至少会在终端上获得cout输出。请注意,我还没有进入内核执行部分,在实际执行和调试内核之前,我只关注内存分配。任何帮助将不胜感激!

我如何检查退货状态:

#define CUDA_SAFE_CALL(call) do {                                      \
  CUDA_SAFE_CALL_NO_SYNC(call);                                         \
  cudaError err = cudaThreadSynchronize();                              \
  if( cudaSuccess != err) {                                             \
     fprintf(stderr, "Cuda error in file '%s' in line %i : %s.\n",      \
                 __FILE__, __LINE__, cudaGetErrorString( err) );        \
     exit(EXIT_FAILURE);                                                \
     } } while (0)
编辑:在我处理了int memcpy和malloc后,错误仍然发生,显然我没有必要分配或cpy它。可能只是把它传了过来。所以,错误是由于以下几行,我不确定是哪一个或为什么?

password* d_pwds;
cudaMalloc( (void**) &d_pwds, mem_size);
cudaMemcpy( d_pwds, h_pwds, mem_size, cudaMemcpyHostToDevice);

libEntry *h_library = (libEntry*) malloc(sizeof(libEntry) * count);

libEntry* d_library;
cudaMalloc( (void**) &d_library, sizeof(libEntry) * count);

EDIT2:我清理了所有东西但仍然无法理解。通过在CUDA_SAFE_CALL后面的行CUDA_SAFE_CALL( cudaMalloc((void**) &d_pwds, pwds_size));,即使每个其他内存分配命令被注释掉,我也会出现分段错误。

1 个答案:

答案 0 :(得分:1)

对于想知道出了什么问题的人,我能够解决它。我不确定到底出了什么问题,但我在某些地方进行了不正确的内存分配,而在其他情况下,我甚至不需要使用cudaMalloccudaMemcpy。此外,使用What is the canonical way to check for errors using the CUDA runtime API?检查错误而不是我自己的实现工作。我现在拥有的:

/***** KERNEL CONFIGURATION & MEMORY MANAGEMENT ******/
/***** GENERATE HASHED PASSWORD LIBRARY FOR COMPARE **/
unsigned int threads_per_block = 1024;
dim3  grid(1024, 1, 1);
dim3  threads(threads_per_block, 1, 1);

password* d_pwds;
ERROR_CHECK( cudaMalloc((void**) &d_pwds, pwds_size));
ERROR_CHECK( cudaMemcpy( d_pwds, h_pwds, pwds_size, cudaMemcpyHostToDevice));

libEntry* d_library;
ERROR_CHECK( cudaMalloc( (void**) &d_library, sizeof(libEntry) * count));

// generateLibraryKernel(int numPwds, password* pwds, libEntry* library)
generateLibraryKernel<<<grid, threads>>>(i, d_pwds, d_library);
ERROR_CHECK( cudaPeekAtLastError() );
ERROR_CHECK( cudaDeviceSynchronize() );

从上面的链接定义ERROR_CHECK

#define ERROR_CHECK(ans) { gpuAssert((ans), __FILE__, __LINE__); }
inline void gpuAssert(cudaError_t code, const char *file, int line, bool abort=true)
{
   if (code != cudaSuccess)
   {
      fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
      if (abort) exit(code);
   }
}

我还没有完全理解CUDA(设备和主机分配)中的内存管理,但我的代码现在可以正常工作了!谢谢大家。