Reputation: 373
[using arm-hisiv300-linux-gcc to compile for Linux based Target board]
I got segmentation fault while I called this function.
uint32_t dir_disp(void)
{
uint32_t err;
uint32_t i;
size_t cnt;
char *str;
char **p;
glob_t glob_results;
err = glob("/home/2019-11-12/H*", GLOB_MARK, 0, &glob_results);
p = glob_results.gl_pathv;
cnt = glob_results.gl_pathc;
for (i=0; i<cnt; i++)
{
printf("[DEBUG] dir_disp: %s\n",p[i]);
}
globfree(&glob_results);
return 0;
}
the above function is called only once from a thread function, the segmentation fault occurred only when there are more than ~100 items matching the pattern "/home/2019-11-12/H*
"
Segmentation fault doesn't occur if:
[Edit]
Sorry but I forgot to mention the segfault occur only after printing all the items matching the pattern.
I checked the ret val of glob()
and found it to be zero. Not changing the original question.
Upvotes: 0
Views: 483
Reputation: 241861
According to the Linux manpage, glob()
is not MT-safe so it is "not safe to call in a multithreaded program".
It's possibly worth noting that Posix does require glob()
to be MT-safe, so this attribute is specific to the Gnu implementation in glibc, and might have to do with Gnu extensions such as the tilde expansion option. All the same, you should be aware of the warning.
Based on the symptoms you report, a possible issue is stack overflow, perhaps related to the use of alloca
or VLAs in the glob
implementation. (I didn't check the source code, though; I have no particular evidence that such features are actually used.) Default stack sizes in multithreaded code tend to be quite small, and code which works fine in a non-MT environment can easily exceed the stack size of a default thread. You could try increasing the stack size when you create the thread(s) which call glob
.
Upvotes: 1
Reputation: 16540
the following proposed code:
Notice how the first parameter to glob()
is written
and now, the proposed code:
#include <stdint.h>
#include <glob.h>
#include <stdio.h>
uint32_t dir_disp(void)
{
int err;
size_t cnt;
char **p;
glob_t glob_results;
err = glob("/home/richard/*", GLOB_MARK, 0, &glob_results);
printf( "err: %d\n", err );
p = glob_results.gl_pathv;
cnt = glob_results.gl_pathc;
for (size_t i=0; i<cnt; i++)
{
printf("[DEBUG] dir_disp: %s\n",p[i]);
}
globfree(&glob_results);
return 0;
}
int main( void )
{
uint32_t result = dir_disp();
printf( "result: %d\n", result );
}
a run of the above code results in:
err: 0
[DEBUG] dir_disp: /home/richard/Desktop/
[DEBUG] dir_disp: /home/richard/Documents/
[DEBUG] dir_disp: /home/richard/Downloads/
[DEBUG] dir_disp: /home/richard/Music/
[DEBUG] dir_disp: /home/richard/OpenMPI/
[DEBUG] dir_disp: /home/richard/Pictures/
[DEBUG] dir_disp: /home/richard/Public/
[DEBUG] dir_disp: /home/richard/Templates/
[DEBUG] dir_disp: /home/richard/Videos/
[DEBUG] dir_disp: /home/richard/examples.desktop
result: 0
there were lots of other directories, but they are not relevant to this answer
Upvotes: 0